我在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
我做错了什么?
答案 0 :(得分:5)
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中有些分数无法准确表达;例如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(或其附近)中引入的关键字,因为浮点模型稍微放松了。