简体   繁体   English

IEEE 754:Javascript vs C

[英]IEEE 754: Javascript vs C

From what I understand, the famous 据我了解,著名的

 (0.1 + 0.2) !== 0.3

gotcha is not actually Javascript's fault. 其实不是Javascript的错。 Thats just the way the IEEE 754 works. 这就是IEEE 754的工作方式。 A similar output happens in Python, which also follows the IEEE 754 rules. 类似的输出在Python中发生,它也遵循IEEE 754规则。

Then how come this particular example works as expected in C, sometimes . 然后, 有时这个特定示例如何在C中按预期工作。 If I do a direct comparison 如果我直接比较

printf("%d\n", (0.1+0.2) == 0.3);

I get the (un?)expected output 0 , but if I put the values into variables or print them out, I get properly rounded answers. 我得到了(un?)预期的输出0 ,但是如果将值放入变量中或将其打印出来,则会得到正确的舍入答案。

C Runnable Example C可运行示例

Is the C implementation of IEEE 754 doing something extra? IEEE 754的C实现是否在做额外的事情? Or is it something completely else that I am missing. 还是我完全想不到的其他东西。

Update 更新

The code sample I posted was broken due to a typo. 我张贴的代码示例由于输入错误而损坏。 Try this one Fixed C Runnable Example 试试这个固定的C可运行示例

But the original Question still remains. 但是原始问题仍然存在。

double d1, d2, d3;
d1 = 0.1;    d2 = 0.2;    d3 = d1 + d2;
printf ("%d\n", ((((double)0.1)+((double)0.2)) == ((double)d3)));
printf ("%.17f\n", d1+d2);
printf ("%d\n", ((d1+d2) == d3));

The output is 输出是

1
0.30000000000000004
1

The rephrased question now is: 现在改写的问题是:

  1. Why (and when, and how) is the C compiler taking the liberty to say that C编译器为什么(以及何时,如何)冒昧地说

    0.3 == 0.30000000000000004 0.3 == 0.30000000000000004

  2. Given all facts, isn't it true that the C implementation is broken, rather than Javascripts'? 鉴于所有事实,是不是C实现被破坏了,而不是Javascript了吗?

Why (and when, and how) is the C compiler taking the liberty to say that C编译器为什么(以及何时,如何)冒昧地说

  0.3 == 0.30000000000000004 

Given all facts, isn't it true that the C implementation is broken, rather than Javascripts'? 鉴于所有事实,是不是C实现被破坏了,而不是Javascript了吗?

It isn't. 不是。

The output given is from this code: 给定的输出来自以下代码:

printf ("%d\n", ((((double)0.1)+((double)0.2)) == ((double)d3)));

but you wrote: 但是你写道:

d1 = 0.1;    d2 = 0.2;    d3 = d1 + d2;

so d3 is not 0.3 , it's 0.30000000000000004 所以d3 不是 0.3 ,它是0.30000000000000004

`printf("%d\n", (0.1+0.2) == 0.3);`

These are DOUBLEs not FLOATs. 这些是DOUBLE而不是FLOAT。

Do: 做:

printf("%d\n", (0.1+0.2) == 0.3);
printf("%d\n", (0.1f+0.2f) == 0.3f);

and voila! 和瞧!

http://codepad.org/VF9svjxY http://codepad.org/VF9svjxY

Output:
0
1

Check out this question. 看看这个问题。 It's about smth else, but ppl using GCC got different results than ppl with MSVC. 这与其他方面有关,但是使用GCC的ppl与使用MSVC的ppl获得了不同的结果。 printing the integral part of a floating point number 打印浮点数的整数部分

Your example code uses 1, 2 and (1+2), which are all exactly representable in double precision floating point. 您的示例代码使用1、2和(1 + 2),它们都可以用双精度浮点数精确表示。 0.1 on the other hand is NOT exactly representable in floating point and thus you get an approximation to this number. 另一方面,浮点数不能精确表示为0.1,因此您可以近似得出该数字。 When adding approximately 0.1 to approximately 0.2 you will get approximately 0.3, but whether that's going to be EXACTLY the same approximation that a compiler would choose when representing 0.3 who can tell. 当将约0.1加到约0.2时,您将得到约0.3,但是这是否与编译器在代表0.3可以说明的情况下选择的近似值完全相同。

The representation is using binary. 表示使用二进制。 Which means it uses 1/2, 1/4, 1/8, 1/16, 1/32 (and so on to a number of precision ....). 这意味着它使用1 / 2、1 / 4、1 / 8、1 / 16、1 / 32(以此类推,以至于许多精度....)。 This means that 0.5, 0.25 etc are exactly able to be represented. 这意味着可以精确地表示0.5、0.25等。 Numbers that aren't an exact sum of binary fractions can be approximated very closely. 不是二进制分数的精确和的数字可以非常接近地近似。

Solution: don't compare floating point numbers to each other. 解决方案:不要将浮点数相互比较。 Compare their difference to some small number that you don't care about. 将它们的差异与您不关心的少量数字进行比较。

#define EPSILON 0.000001
printf("%d", fabs((0.1+0.2) - 0.3 ) < EPSILON );

I'm not sure why the C code works and the python/javascript doesn't. 我不确定为什么C代码可以工作而python / javascript无法工作。 It's magic. 这是魔法。 But hopefully this answers your question anyway. 但是希望这仍然可以回答您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM