工作小数点数

时间:2013-12-10 12:08:03

标签: java floating-point-precision

我在java中编写了一个关于浮点的程序,但得到的输出并不准确;而用C语言编写的相同程序确实产生了准确的结果。

代码段:

public class One {

public static void main(String...args){

    double i, num=0.0;
    for(i=0;i<10;i++)
    num=num+0.1;
    System.out.println(num);

    }
}

输出:0.9999999999999999

C中的程序就像这样

#include<stdio.h>
main()
{

double i,num=0.0;
for(i=0;i<10;i++)
num=num+0.1;

printf("%f",num);

}

输出:1.00000

我做错了什么?

5 个答案:

答案 0 :(得分:5)

C隐藏了不删除它的问题

C程序更准确的想法是对正在发生的事情的误解。两者都有不精确的答案但是默认情况下C已经四舍五入到6位有效数字。 隐藏微小的错误。如果您实际使用计算中的值(例如num==1),您会发现两者都不准确。

通常对编写良好的程序无关紧要

通常,智能编写的程序可以毫无困难地处理这个微小的错误。例如,您的程序可以重写以每次重新创建一个双重

double i, num=0.0;
for(i=0;i<10;i++)
   num=0.1*i;
   System.out.println(num);

}

意味着错误不会增长。另外,你不应该使用== with double,因为那里可以看到微小的不准确性。

在非常偶然的情况下,这个小错误是一个问题(货币计划是最常见的);可以使用bigDecimal。

这不是浮点数的问题,而是从基数10到基数2的转换。

基数10中有些分数无法准确表达;例如1/3。类似地,存在不能在二进制内精确表达的分数,例如1/10。 It is from this perspective that you should look at this

在这种情况下的问题是,当您写入“0.1”时,计算机必须将其转换为二进制数字0.1=(binary)0.00011001100110011001100110011001.......的基数为10,但因为它无法准确地表示二进制数字它所拥有的空间最终为(binary)0.000110011001100 1 。二进制友好数字(例如1/2)将完全准确,直到精确数字的双精度(此时甚至无法准确表示二进制友好数字)

1 小数位数不准确

答案 1 :(得分:2)

尝试使用BigDecimal。浮点数表示是Java的一个古老的问题点(而不仅仅是)。

double i;
BigDecimal num = BigDecimal.ZERO;
for(i=0;i<10;i++)
    num = num.add(new BigDecimal("0.1"));
System.out.println(num);

答案 2 :(得分:1)

问题不在于Java,而在于计算机如何用二进制表示浮点数。有些数字无法准确表示,因此在添加0.1时会出现一些舍入错误。我建议您阅读this great article以获取详细说明。此外,还有algorithms专门用于在添加数字序列时将错误降至最低。

答案 3 :(得分:0)

这是floating号码表示中的问题。使用BigDecimal

您可以在此处了解此问题。如果你运行以下代码,

    double i, num=0.0;
    for(i=0;i<10;i++) {
        System.out.println(num);
        num=num+0.1;
    }
    System.out.println(num);

Out put

0.0
0.1
0.2
0.30000000000000004 // wrong value, it should be 0.3
0.4
0.5
0.6
0.7
0.7999999999999999 // this one should be 0.7+0.1=0.8
0.8999999999999999 // this should be 0.8+0.1=0.9
0.9999999999999999 // final result should be 0.9+0.1=1

让我们试试BigDeciaml

 double i;
 BigDecimal num=BigDecimal.ZERO;
 for(i=0;i<10;i++) {
     System.out.println(num);
     num=num.add(new BigDecimal("0.1"));
   }
 System.out.println(num);

Out put

0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0

答案 4 :(得分:0)

strictfp个关键字,例如:

strictfp class Example
{
    //your code here
}

strictfp是Java SE 2(或其附近)中引入的关键字,因为浮点模型稍微放松了。