use*_*882 2 c c++ java decimal decimal-point
假设我们有这种循环(伪代码)
double d = 0.0
for i in 1..10 {
d = d + 0.1
print(d)
}
Run Code Online (Sandbox Code Playgroud)
在C与printf("%f", d)
我得到这个:
0.100000
0.200000
0.300000
...
1.000000
Run Code Online (Sandbox Code Playgroud)
在C++中,cout << d
我得到了这个:
0.1
0.2
...
1
Run Code Online (Sandbox Code Playgroud)
在Java中,System.out.println(d)
我得到了这个:
0.1
0.2
0.3 (in debug mode, I see 0.30000000000004 there but it prints 0.3)
...
0.7
0.799999999999999
0.899999999999999
0.999999999999999
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
为什么这个简单的代码用Java打印得如此糟糕且在C中是否正确?
由于您没有比较相同的操作,因此会得到不同的结果.
double
不同语言的行为完全相同,因为它使用硬件在每种情况下执行这些操作.唯一的区别是您选择显示结果的方法.
在Java中,如果你运行
double d = 0;
for (int i = 1; i <= 10; i++)
System.out.printf("%f%n", d += 0.1);
Run Code Online (Sandbox Code Playgroud)
它打印
0.100000
0.200000
0.300000
0.400000
0.500000
0.600000
0.700000
0.800000
0.900000
1.000000
Run Code Online (Sandbox Code Playgroud)
如果你跑
double d = 0;
for (int i = 0; i < 8; i++) d += 0.1;
System.out.println("Summing 0.1, 8 times " + new BigDecimal(d));
System.out.println("How 0.8 is represented " + new BigDecimal(0.8));
Run Code Online (Sandbox Code Playgroud)
你得到
Summing 0.1, 8 times 0.79999999999999993338661852249060757458209991455078125
How 0.8 is represented 0.8000000000000000444089209850062616169452667236328125
Run Code Online (Sandbox Code Playgroud)
正如这里所回答的,这与任何语言无关.
请参阅:每个程序员应该知道的浮点运算
实数是无限的.计算机正在使用有限数量的位(32位,今天64位).因此,计算机完成的浮点运算不能代表所有实数.0.1是这些数字之一.
请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机代表实数的方式.