Strange behaviour, multiplying decimals (IE)

C

craigslist.jg

Hi,

I'm building an IE-centric portal for an intranet so I've only had to
develop for IE 6+

My version is: 6.00290.2180

Here's what I'm seeing:

0.25 * 100 = 25
0.26 * 100 = 26
0.27 * 100 = 27

ok so far....

0.28 * 100 = 28.000000000000003
0.29 * 100 = 28.999999999999996


Not what I expected.


curiously, 0.299 yields what I'd expect, 29.9
Also, 0.299 * 1000 = 299, which is correct!

I iterated from 0.01 to 0.99 and these other combinations produce a
similar output:

0.07 * 100 = 7.000000000000001
0.14 * 100 = 14.000000000000001
0.55 * 100 = 55.00000000000001
0.56 * 100 = 56.00000000000001
0.57 * 100 = 56.99999999999999
0.58 * 100 = 57.99999999999999


Anyone know of a safe way of doing multiplication which will produce
the correct result and the right number of digits?

Thanks!
 
C

craigslist.jg

wrote on 26 sep 2007 in comp.lang.javascript:


<http://www.jibbering.com/faq/#FAQ4_7>



Initially I couldn't figure out how to use the code in 4.6. I finally
realized that the toFixed() protype was being overriden and all I had
to do was use it as follows:

before:
..29 * 100 = 28.999999999999996

after:
(.29 * 100).toFixed(0) = 29. (then I regex the decimal out)

Perhaps an example or an explanation is needed in the faq?

thanks!
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
egroups.com>, Wed, 26 Sep 2007 12:28:22, (e-mail address removed) posted:
The reference in that section is all very well, though the references to
Jscript may confuse the unwary a bit. But there should be a more user-
friendly URL that could be given as well.

Don't quote signatures,
Initially I couldn't figure out how to use the code in 4.6.

Evertjan cited 4.6. He did not cite 4.6.
I finally
realized that the toFixed() protype was being overriden and all I had
to do was use it as follows:

before:
.29 * 100 = 28.999999999999996

after:
(.29 * 100).toFixed(0) = 29. (then I regex the decimal out)

If you know you want an integer, don't use toFixed or StrS; use
Math.round.

Perhaps an example or an explanation is needed in the faq?

The version of function StrU in the FAQ is well-known to be out-of-date.

Method toFixed (bugs in the original apart) is OK for those who love
Methods. You can use StrS itself directly. Or StrU StrT StrW.

<FAQENTRY> To FAQ 4.7, new para 2.5 : "Otherwise, use Math.round on the
results of expressions which should be of integer value."; and move the
last sentence of 2.0 to precede that in 2.5.
 
E

Evertjan.

wrote on 26 sep 2007 in comp.lang.javascript:

[please do not quote signatures on usenet,
any decent newsreader will skip those for you automagically]
Initially I couldn't figure out how to use the code in 4.6. I finally
realized that the toFixed() protype was being overriden and all I had
to do was use it as follows:

No, the default toFixed(n) was overridden, as it has a bug [in IE?]
before:
.29 * 100 = 28.999999999999996

after:
(.29 * 100).toFixed(0) = 29. (then I regex the decimal out)

Perhaps an example or an explanation is needed in the faq?

4.6 indirectly states that that toFixed(n) needs n>0

Will this save your day?

alert( +(.29 * 100).toFixed(0) );

[Look, no Regex]
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>
wrote on 26 sep 2007 in comp.lang.javascript:

No, the default toFixed(n) was overridden, as it has a bug [in IE?]

The functions StrU StrS StrT StrW are more capable than method toFixed,
as they allow fixing the number of characters before the decimal point,
which is useful in Tables. Replacing default toFixed is a minor
addition. That should be emphasised in the FAQ, perhaps by adding a
comment line before the last line of code :
// StrS can be used to implement a better toFixed method


Method replace does not require a RegExp. With a string for its first
parameter it is twice as fast, and code seems then of similar speed to
code using substring.

4.6 indirectly states that that toFixed(n) needs n>0

ISO/IEC 16262 allows n=0. However, it requires a decimal point, giving
a result incompatible with general good practice (IUPAP/SUNAMCO, IIRC,
refers) which is to have at least one digit on each side of the point;
that is why 4.6 disdains n=0. It does not state that n>0 is needed.

Will this save your day?

alert( +(.29 * 100).toFixed(0) );

[Look, no Regex]

But it converts a Number to a String with toFixed, then back to a Number
with unary plus (which alert converts to String display). Math.round
should be much faster (nearly 4 times so, in IE6, it seems).

This function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
would be better than the Sign in the FAQ, particularly for use in Tables
(a sensible font will have plus minus and space all of the same width as
a digit). A newbie can more easily remove unwanted parts than add
missing ones.


It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 
E

Evertjan.

Randy Webb wrote on 27 sep 2007 in comp.lang.javascript:
I am curious how you cite something you did not cite.

The exegesis of the faq offers hidden gems.
 
C

craigslist.jg

wrote on 26 sep 2007 in comp.lang.javascript:

[please do not quote signatures on usenet,
any decent newsreader will skip those for you automagically]



That's the magic of Google.


Initially I couldn't figure out how to use the code in 4.6. I finally
realized that the toFixed() protype was being overriden and all I had
to do was use it as follows:

No, the default toFixed(n) was overridden, as it has a bug [in IE?]
before:
.29 * 100 = 28.999999999999996
after:
(.29 * 100).toFixed(0) = 29. (then I regex the decimal out)
Perhaps an example or an explanation is needed in the faq?

4.6 indirectly states that that toFixed(n) needs n>0

Will this save your day?

alert( +(.29 * 100).toFixed(0) );

[Look, no Regex]

Yea, that's much nicer and it works.. thanks.
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>
Randy Webb wrote on 27 sep 2007 in comp.lang.javascript:


The exegesis of the faq offers hidden gems.

Regrettably, the 6 in the main block my keyboard is dangerously close to
the 7. I should have used the keypad.

Let us hope that Randy has taken due cognisance of the rest of the
article.
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>
Dr J R Stockton wrote on 27 sep 2007 in comp.lang.javascript:


We were discussing another toFixed(n),
not the default one.

From the above, and from the code for the substitute toFixed in the FAQ,
one can see that n=0 is allowed in both cases.

But n=0 should not be used in either case, as it gives a string ending
in a decimal point, unless some constraint forces that to be used.
 
E

Evertjan.

FAQEditor wrote on 28 sep 2007 in comp.lang.javascript:
Dr J R Stockton said the following on 9/27/2007 6:06 AM:



Replaced locally.

Just playing:

function Sign(X) {return ' -+'.charAt(!X?0:X<0?1:2)}

function Sign(X) {return ' -+'.split('')[!X?0:X<0?1:2]}
 
D

Dr J R Stockton

In comp.lang.javascript message said:
Dr J R Stockton said the following on 9/26/2007 4:47 PM:

No; I posted it at Wed, 26 Sep 2007 21:47:19 +0100, having written it
before that time.

Then perhaps you would care to post a new updated version? And I will
be happy to add it. I am not going to hunt it down and guess at it
though.

If you find the link in the FAQ inadequate, please explain why. It's
only one obvious step from there to js-rndg1.htm#GC .

Added locally.


I have to assume that your "2.0" is a typo as I have no 2.0 in my local
version.

If you understand "2.5", you should be able to understand "2.0". The
recommendation amounts to shifting a paragraph break.
 
E

Evertjan.

Dr J R Stockton wrote on 28 sep 2007 in comp.lang.javascript:
In comp.lang.javascript message Evertjan. posted:

function Sign(X) {return '+ -'.charAt(X<0?2:!X)} // is shorter

Indeed.

This one is longer, but does not use any tertiary operator:

function Sign(X) {return ' +-'.charAt(!!X+(X<0))}

would it be faster?
 
E

Evertjan.

Evertjan. wrote on 29 sep 2007 in comp.lang.javascript:
Dr J R Stockton wrote on 28 sep 2007 in comp.lang.javascript:

Indeed.

This one is longer, but does not use any tertiary operator:

function Sign(X) {return ' +-'.charAt(!!X+(X<0))}

Or we could compute the characters from their unicode value:

function Sign(X) {return String.fromCharCode(43-!X*11+(X<0)*2)}
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>
Dr J R Stockton wrote on 28 sep 2007 in comp.lang.javascript:
This one is longer, but does not use any tertiary operator:

function Sign(X) {return ' +-'.charAt(!!X+(X<0))}

would it be faster?


Even including the one you posted next, the differences are
insignificant, and will depend on the sign of the argument and
therefore, overall, on the proportion of positive, negative, zero.

As most results are positive (IMHO), this should be insignificantly
better :

function Sign(X) {return '- +'.charAt(X>0?2:!X)}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,404
Latest member
PerryRutt

Latest Threads

Top