[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

IE and IEE 754

RobG

8/27/2014 12:45:00 PM

In most browsers:

0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999

in IE it returns:

12.479999999999998

Is IE wrong, or is the above difference allowable within IEEE 754?


--
Rob
55 Answers

John Harris

8/27/2014 2:23:00 PM

0

On Wed, 27 Aug 2014 22:44:35 +1000, RobG <rgqld@iinet.net.au> wrote:

>In most browsers:
>
> 0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999
>
>in IE it returns:
>
> 12.479999999999998
>
>Is IE wrong, or is the above difference allowable within IEEE 754?

It's possible both are right. According to Wikipedia :
"The standard requires operations to convert between basic formats and
external character sequence formats.[12] Conversions to and from a
decimal character format are required for all formats. Conversion to
an external character sequence must be such that conversion back using
round to even will recover the original number."

John

PS I've corrected the typo in the Subject. The late lamented IEE is no
more, alas.

Thomas 'PointedEars' Lahn

8/27/2014 7:00:00 PM

0

RobG wrote:

> In most browsers:
>
> 0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999
>
> in IE it returns:
>
> 12.479999999999998

Probably neither is true.

> Is IE wrong, or is the above difference allowable within IEEE 754?

Mu. You need to keep in mind that in this way you are only seeing string
representations of Number values, specified in
<http://ecma-international.org/ecma-262/5.1/#sec.... (Is there even
another way?)

If I understand it correctly, there is enough room in the algorithm and
implementation notes for this to be implementation-dependent. Even if it
were not, or implementors would not defer to any allowances, the wording of
the algorithm is so complicated, even for Ecma standards (pun intended),
that I would not be surprised if, because of that, different implementors
would arrive at different implementations of it.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Evertjan.

8/27/2014 8:05:00 PM

0

RobG <rgqld@iinet.net.au> wrote on 27 aug 2014 in comp.lang.javascript:

> In most browsers:
> 0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999
> in IE it returns:
> 12.479999999999998
> Is IE wrong, or is the above difference allowable within IEEE 754?

Both are and must be wrong in the sense that the binary converions
of floting point fractional decimal values NEVER can be right.

So why use a standard that defines how wrong they must be?

Just remember every time,
that you should not compare such values without prior rounding.

If you are a sticker for correctness and these are monitary values,
like $ or ?, use integer cent values in variables, and write decimals with
string manupulation.

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Christoph M. Becker

8/27/2014 8:09:00 PM

0

RobG wrote:

> In most browsers:
>
> 0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999
>
> in IE it returns:
>
> 12.479999999999998
>
> Is IE wrong, or is the above difference allowable within IEEE 754?

Both string representations will be parsed as the same double-precision
64-bit binary format IEEE 754 value[1]:

100000000101000111101011100001010001111010111000010100011110101

(Therefore: 12.479999999999999 === 12.479999999999998)

The different string representation is allowed for conforming ECMAScript
implementations according to ECMA-262 5.1 Edition, section 9.8.1 step 5[2].

[1] <http://www.merlyn.demon.co.uk/js-exact.h...
[2] <http://ecma-international.org/ecma-262/5.1/#sec...

--
Christoph M. Becker

Christoph M. Becker

8/27/2014 8:35:00 PM

0

Evertjan. wrote:

> RobG <rgqld@iinet.net.au> wrote on 27 aug 2014 in comp.lang.javascript:
>
>> In most browsers:
>> 0.57 + 8.36 + 3.36 + 0.19 = 12.479999999999999
>> in IE it returns:
>> 12.479999999999998
>> Is IE wrong, or is the above difference allowable within IEEE 754?
>
> Both are and must be wrong in the sense that the binary converions
> of floting point fractional decimal values NEVER can be right.

Wrong. Consider e.g. 0 or 2.

> So why use a standard that defines how wrong they must be?

To be able to quantify the inaccuracy.

> Just remember every time,
> that you should not compare such values without prior rounding.

AFAIK it is common to compare for equality with

Math.abs(a - b) < epsilon

See also Number.EPSILON[1].

> If you are a sticker for correctness and these are monitary values,
> like $ or ?, use integer cent values in variables, and write decimals with
> string manupulation.

Are you suggesting that storing $123.45 as 12345 is better than storing
it as 123.45? As ECMAScript implementations typically have no integer
type, there is no difference regarding the precision of further
calculations.

[1]
<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.e...

--
Christoph M. Becker

Evertjan.

8/27/2014 10:08:00 PM

0

"Christoph M. Becker" <cmbecker69@arcor.de> wrote on 27 aug 2014 in
comp.lang.javascript:

>> Both are and must be wrong in the sense that the binary converions
>> of floting point fractional decimal values NEVER can be right.
>
> Wrong. Consider e.g. 0 or 2.

No 0 and 2 are integers.

>> So why use a standard that defines how wrong they must be?
>
> To be able to quantify the inaccuracy.

There is no need for that.

>> Just remember every time,
>> that you should not compare such values without prior rounding.
>
> AFAIK it is common to compare for equality with
>
> Math.abs(a - b) < epsilon

What has "common" to do with it?

It is a way,
but a and b stay unrounded,
and if reused and reused
you might find yourself in trouble
with the wrong value of epsilon.

> See also Number.EPSILON[1].

I don't see that.

>
>> If you are a sticker for correctness and these are monitary values,
>> like $ or , use integer cent values in variables, and write decimals
>> with string manupulation.
>
> Are you suggesting that storing $123.45 as 12345 is better than storing
> it as 123.45?

I am not 'suggesting' anything,
I am not saying 'better',
just read my words.

But indeed, it is safer to manipulate integers.

> As ECMAScript implementations typically have no integer
> type, there is no difference regarding the precision of further
> calculations.

I wes not talking about the integer type,
I was not talking about Javascript [ECMA if you like],
but about integers.

There is a rather a big difference
'regarding the precision of further calculations.'
that difference is called safety of exactness.

Integers in binary storage are exact
and so are simple arithmetic with those numbers, except for division,
as long as the precision stays within practical limits.

input '23.45' string, store as a = 2345
input '23.4' string, store as b = 2340
do c = a - b
c contains 5
convert c to string d 0.05
write d

Compare this to:

document.write(23.45-23.4); // 0.05000000000000071

You are quite in your right
not to call the first method "better",
but in monetary calculus, I would disagree.

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Christoph M. Becker

8/27/2014 10:47:00 PM

0

Evertjan. wrote:

> "Christoph M. Becker" <cmbecker69@arcor.de> wrote on 27 aug 2014 in
> comp.lang.javascript:
>
> I wes not talking about the integer type,
> I was not talking about Javascript [ECMA if you like],
> but about integers.

Well, then you're off topic.

> Compare this to:
>
> document.write(23.45-23.4); // 0.05000000000000071
>
> You are quite in your right
> not to call the first method "better",
> but in monetary calculus, I would disagree.

Well, then try to calculate the German VAT with "integers":

2345 * 1.19 -> 2790.5499999999997

Ah, we have to round the result:

(2345 * 1.19).toFixed(0) -> 2791

Or:

(23.45 * 1.19).toFixed(2) -> 27.91

Hm, same result (but see <http://www.jibbering.com/faq/#format...
for very old browsers).

Anyway, you can't do arbitrary monetary calculations reliably with IEEE
754 doubles. However, that is the only number type that is guaranteed
to be supported by conforming ECMAScript implementations.

--
Christoph M. Becker

Ben Bacarisse

8/27/2014 11:00:00 PM

0

"Christoph M. Becker" <cmbecker69@arcor.de> writes:

> Evertjan. wrote:
<snip>
>> If you are a sticker for correctness and these are monitary values,
>> like $ or [euro-sign], use integer cent values in variables, and
>> write decimals with string manupulation.
>
> Are you suggesting that storing $123.45 as 12345 is better than storing
> it as 123.45? As ECMAScript implementations typically have no integer
> type, there is no difference regarding the precision of further
> calculations.

12345 can be represented exactly in binary floating point (given enough
bits, and we certainly have that) whereas 123.45 can't be. Whether this
matters (and how much) depends on what calculations you go on to do, but
I would call that a difference in precision from the get go.

--
Ben.

Ben Bacarisse

8/27/2014 11:06:00 PM

0

"Evertjan." <exxjxw.hannivoort@inter.nl.net> writes:
<snip>
> Both are and must be wrong in the sense that the binary converions
> of floting point fractional decimal values NEVER can be right.

What about 0.5 or 0.25? Why can't these ever be right? Did you mean
that *all* decimal fractions can't be correctly converted? That's
certainly the case. The way you worded it sounds like none of them can
be.

<snip>
--
Ben.

Christoph M. Becker

8/28/2014 12:56:00 AM

0

Ben Bacarisse wrote:

> "Christoph M. Becker" <cmbecker69@arcor.de> writes:
>
>> Evertjan. wrote:
> <snip>
>>> If you are a sticker for correctness and these are monitary values,
>>> like $ or [euro-sign], use integer cent values in variables, and
>>> write decimals with string manupulation.
>>
>> Are you suggesting that storing $123.45 as 12345 is better than storing
>> it as 123.45? As ECMAScript implementations typically have no integer
>> type, there is no difference regarding the precision of further
>> calculations.
>
> 12345 can be represented exactly in binary floating point (given enough
> bits, and we certainly have that) whereas 123.45 can't be.
<snip>

Thanks for pointing this out. :) After quite some reconsideration I have
to admit that I was wrong. Of course, 123.45 can't be represented
exactly as *binary* floating point number, while 12345 can be.

However, it seems to me that multiplying 123.45 (0x405edccccccccccd)
with 100 doesn't solve the issue, i.e. the result is not necessarily
equal to 12345 (0x40c81c8000000000).

--
Christoph M. Becker