Java、C、C+中十进制数的精度+;及其他
假设我们有这种循环(伪代码) 在C中,使用Java、C、C+中十进制数的精度+;及其他,java,c++,c,decimal,decimal-point,Java,C++,C,Decimal,Decimal Point,假设我们有这种循环(伪代码) 在C中,使用printf(“%f”,d) 0.100000 0.200000 0.300000 ... 1.000000 0.1 0.2 ... 1 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 C++中的 >代码> 因为打印例程的行
printf(“%f”,d)
0.100000
0.200000
0.300000
...
1.000000
0.1
0.2
...
1
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
C++中的>代码>
>>> print('%.20f' % (.1 * 8))
0.80000000000000004441
>>> d = .0
>>> for i in xrange(10):
... d += .1
... print('%.20f' % d)
...
0.10000000000000000555
0.20000000000000001110
0.30000000000000004441
0.40000000000000002220
0.50000000000000000000
0.59999999999999997780
0.69999999999999995559
0.79999999999999993339
0.89999999999999991118
0.99999999999999988898
但请注意:
>>> print('%.20f' % .8)
0.80000000000000004441
double
的行为完全相同,因为它在每种情况下都使用硬件来执行这些操作。唯一的区别是您选择的显示结果的方法
在Java中,如果您运行
double d = 0;
for (int i = 1; i <= 10; i++)
System.out.printf("%f%n", d += 0.1);
如果你跑
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));
正如所回答的,这与任何语言都无关
请看这里:
实数是无限的。计算机的工作位数是有限的(现在是32位,64位)。因此,计算机所做的浮点运算不能代表所有的实数。0.1是这些数字之一
请注意,这与Ruby无关,但与所有编程语言有关,因为它来自计算机表示实数的方式。这些不是十进制数,而是二进制数。好好学习这一点。StackOverflow需要一个贝叶斯过滤器,它可以自动在新帖子中查找单词“Decimal”和“Precision”…这是否意味着在每种语言中,双精度值0.8都存储为0.7999999999?因为在变量视图的调试模式下,我可以看到这个丑陋的值。@Tomas:计算
.8
的方式产生.799999999993339
,但如果您只输入文本,您将得到.800000000000004441
。不,0.8的值不精确,但总和或0.1+0.1+。。。0.1略小于0.8的表示形式。请参阅我的编辑。如果使用新的BigDecimal(double)
构造函数构造一个BigDecimal
,它将具有与传递的double
完全相同的值,这意味着新的BigDecimal(0.1)
将具有“错误”的值。改用new BigDecimal(String)
构造函数,它的值将是精确的,也就是说new BigDecimal(“0.1”)
的值将是精确的0.1。@Peter Lawrey我同意,我刚才为Tomas指出了这一点。
0.100000
0.200000
0.300000
0.400000
0.500000
0.600000
0.700000
0.800000
0.900000
1.000000
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));
Summing 0.1, 8 times 0.79999999999999993338661852249060757458209991455078125
How 0.8 is represented 0.8000000000000000444089209850062616169452667236328125