Java 双数据类型上的大量操作会产生零
我有一个程序,它将概率乘以500倍,但当我这样做时,输出为零。我应该使用其他数据类型吗? 请帮忙。 以下是我正在使用的代码:Java 双数据类型上的大量操作会产生零,java,floating-point,double,Java,Floating Point,Double,我有一个程序,它将概率乘以500倍,但当我这样做时,输出为零。我应该使用其他数据类型吗? 请帮忙。 以下是我正在使用的代码: double d = 1/80000d; for (int i = 0; i < 500; i++) { d *= d; } System.out.println(d); 双d=1/80000d; 对于(int i=0;i
double d = 1/80000d;
for (int i = 0; i < 500; i++) {
d *= d;
}
System.out.println(d);
双d=1/80000d;
对于(int i=0;i<500;i++){
d*=d;
}
系统输出打印ln(d);
输出为零,因为double
的感知能力有限,如果将小于1的数字乘以足够的次数,结果将太小,无法与0区分开来
如果在每次迭代后打印d
,您将看到它很快变为0:
1.5625E-10
2.4414062500000002E-20
5.960464477539064E-40
3.552713678800502E-79
1.2621774483536196E-157
1.593091911E-314
0.0
当然,如果您有两个小于1的数字,并且早晚重复乘法次数将足够小,以至于将来无法用双精度、扩展或任何浮点运算来表示。;) 轮到您的是已存储在类型中的近似值。零是IEEE 754格式的特殊常数之一
我不懂JAVA,但存在其他语言中扩展的类型。在处理概率时,您可以通过使用对数来避免此类数字问题,这样您就可以进行额外的处理。差不多
double d = 1/80000d;
double ld = Math.log(d)
for (int i = 0; i < 500; i++) {
ld += ld;
}
System.out.println(ld);
双d=1/80000d;
双ld=Math.log(d)
对于(int i=0;i<500;i++){
ld+=ld;
}
系统输出打印项次(ld);
我应该怎么做才能保持精度?@Ankitan并尝试使用BigDecimal在这样做之前,请检查您是否确实需要表示这么小的数字。如果您确实需要计算d^500或其他数字,有更简单的方法来计算,而且在这种情况下,结果确实是常数,但是结果仍然无法在双精度范围内表示。
您确定这是您需要做的吗?