Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java、C、C+中十进制数的精度+;及其他_Java_C++_C_Decimal_Decimal Point - Fatal编程技术网

Java、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++中的 >代码> 因为打印例程的行

假设我们有这种循环(伪代码)

在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++中的

>代码>

  • 因为打印例程的行为方式<代码>0.1不能以二进制浮点格式精确表示
  • 在Python中:

    >>> 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
    
  • 为什么这个简单的代码在Java中打印得如此糟糕,并且在C中是正确的

    由于您没有比较相同的操作,因此将得到不同的结果

    在不同的语言中,
    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