执行以下代码时:
public class FPoint {
public static void main(String[] args) {
float f = 0.1f;
for(int i = 0; i<9; i++) {
f += 0.1f;
}
System.out.println(f);
}
}
显示以下输出:
1.0000001
但输出应该 1.0000000 ,对吗?如果我错了,请纠正我...... !!
答案 0 :(得分:7)
0.1实际上并非“0.1”。
0.1编码:0 01111011 10011001100110011001101
(带浮点数)
要转换十进制数的尾数,我们有 1.10011001100110011001101 * 2 ^ -4 (base2)[1.xxx隐含在IEEE 754中]
= 0.000110011001100110011001101(base2)
= 1/2 ^ 4 + 1/2 ^ 5 + 1/2 ^ 8 + 1/2 ^ 9 + 1/2 ^ 12 + 1/2 ^ 13 + 1/2 ^ 16 + 1/2 ^ 17 + 1 ^ 2 ^ 20 + 1/2 ^ 21 + 1/2 ^ 24 + 1/2 ^ 25 + 1/2 ^ 27(base10)
= 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 + 1/131072 ......(base10)
= 0.10000000149011612 (base10)
答案 1 :(得分:4)
就像我们的十进制系统中的某些实数(如1/3)无法准确表达一样,某些数字(如1/10)无法用二进制表示。
1/3=(decimal)0.33333333333 (3) recurring
1/10=(binary)0.00011001100 (1100) recurring
因为我们对小数非常熟悉,所以很明显1/3无法准确表示,但对于具有基数为3的系统的人来说,这似乎是对小数的一个主要限制;
1/3=(base 3)0.1
因为这样的1/10在浮点数中不精确地表示,并且通过将多个不精确的数字加在一起,你会得到一个不准确的答案。
在此上下文中,您应该解释浮点错误。如果您有一个在十进制内可以完全表示但不在二进制内的数字,那么您可能会发现BigDecimal很有用。但是你不应该认为BigDecimal比浮点数更好;它只是有一组不同的数字,它不能完全代表;你习惯的那套。 BigDecimal还尝试在二进制处理器上使用十进制计数系统;因此,它的计算效率低于基于双/浮点的计算
答案 2 :(得分:0)
如果您需要精确计算,例如处理非常敏感的数据时,请不要使用float
或double
,它们在二进制中的表示使用近似值。请查看此article以获得一些不错的解释。
答案 3 :(得分:-1)
这是一种常见的误解。这种“错误”与浮点数据结构有关:读this。在这种情况下,您可以使用double
来获得更高的精确度。