对于此代码段
double count = 0.0;
while( count != 1.0)
{count += 1.0/3;}
我想知道(IEEE 754)的哪些部分会导致计数3:为1.0而不是.9999999999999999。我意识到由于无限数量的二进制数字,一般的原因将是四舍五入,但如果有人可以详细解释这背后的(IEEE 754)细节,我将不胜感激。
答案 0 :(得分:0)
没有一般规则可确保添加n
1.0/n
份副本会产生1.0
。可以通过更改以下程序中的n
来探索这一点:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
int n = 3;
double[] counts = new double[n+1];
for(int i=1; i<counts.length; i++){
counts[i] = counts[i-1]+1.0/n;
}
for(double count : counts){
System.out.println(new BigDecimal(count));
}
}
}
对于n=3
,它会打印:
0
0.333333333333333314829616256247390992939472198486328125
0.66666666666666662965923251249478198587894439697265625
1
第一次加法增加为零。第二个添加是简单的加倍,所以它也是准确的。第三次也是最后一次加法涉及四舍五入,但轮次为1.0
。添加的确切结果是:
0.999999999999999944488848768742172978818416595458984375
它接近1.0而不是下一个值:
0.99999999999999988897769753748434595763683319091796875
如此圆到最近的几轮到1.0。
但是,将n
更改为7
会导致:
0
0.142857142857142849212692681248881854116916656494140625
0.28571428571428569842538536249776370823383331298828125
0.428571428571428547638078043746645562350749969482421875
0.5714285714285713968507707249955274164676666259765625
0.7142857142857141905523121749865822494029998779296875
0.8571428571428569842538536249776370823383331298828125
0.9999999999999997779553950749686919152736663818359375
运行修改为添加1.0/7
的原始程序会导致无限循环。 count
会增加,直到它变得如此之大,以至于添加1.0/7
将会转换为旧值,然后停留在该值。