tun*_*nuz 30 java sum floating-accuracy
我有一个非常恼人的问题,在Java中有很多浮点数或双打数.基本上这个想法是,如果我执行:
for ( float value = 0.0f; value < 1.0f; value += 0.1f )
System.out.println( value );
Run Code Online (Sandbox Code Playgroud)
我得到的是:
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001
Run Code Online (Sandbox Code Playgroud)
我明白浮动精度误差的积累,但是,如何摆脱这个?我尝试使用双打错误的一半,但结果仍然相同.
有任何想法吗?
Mar*_*ers 33
没有精确表示0.1作为float
或double
.由于此表示错误,结果与您的预期略有不同.
您可以使用以下几种方法:
double
类型时,只显示所需数量的数字.检查相等性时,允许任何一种小容差.BigDecimal
可以精确地表示0.1.示例代码BigDecimal
:
BigDecimal step = new BigDecimal("0.1");
for (BigDecimal value = BigDecimal.ZERO;
value.compareTo(BigDecimal.ONE) < 0;
value = value.add(step)) {
System.out.println(value);
}
Run Code Online (Sandbox Code Playgroud)
在线查看:ideone
你可以使用像这样的类来避免这个特定问题BigDecimal
.float
并且double
,作为IEEE 754浮点,它们的设计并不完全准确,它们的设计速度很快.但请注意Jon的观点如下:BigDecimal
不能准确地代表"三分之一",double
不能准确地代表"十分之一".但是对于(比如说)财务计算,BigDecimal
类似的课程往往是要走的路,因为它们可以用我们人类倾向于思考它们的方式来表示数字.
不要在迭代器中使用float/double,因为这会最大化舍入误差.如果你只是使用以下
for (int i = 0; i < 10; i++)
System.out.println(i / 10.0);
Run Code Online (Sandbox Code Playgroud)
它打印
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
Run Code Online (Sandbox Code Playgroud)
我知道BigDecimal是一个受欢迎的选择,但我更喜欢双倍,因为它更快但通常更短/更清晰.
如果计算符号数量作为代码复杂度的度量
BTW:除非有不使用浮动真的很好的理由不使用双.