Java-当倍数都是小而长的小数时,它们加在一起等于无穷大

  • 本文关键字:加在一起 无穷大 小数 Java- java
  • 更新时间 :
  • 英文 :


我有一行代码,它把几个双精度加在一起,得到的结果是无穷大,而双精度都只是小而长的小数

a = -1.536709757154733E308
b =  2.102331119338414E156
c =  0.2
d = a - b + (a * c)
d = -1.536709757154733E308 - 2.102331119338414E156 + (-1.536709757154733E308 * 0.2)
d = -infinity

有人知道为什么会发生这种事吗?如有任何帮助,将不胜感激

PS在该代码中使用大小数是不可行的,并且由于每次运行时随机的"a"one_answers"b"变化

发生溢出。表达式a - b + (a * c)的结果的大小大于最大可能的doubleDouble.MAX_VALUE1.7976931348623157E308。当这种情况发生时,结果是无穷大。因为a是阴性的,这导致了-Infinity

如果你把ab的指数减少1,你可以看到这个结果:

-1.8440517085856795E307

在结果中再次将指数增加1将产生大于最大可能幅度的幅度。

您仍然可以使用BigDecimals。

BigDecimal a =  new BigDecimal(-1.536709757154733E308);
BigDecimal b =  new BigDecimal(2.102331119338414E156);
BigDecimal c =  new BigDecimal(0.2);
System.out.println(a.add(b).add(a.multiply(c)));

小数点在欺骗你。要查看double的实际值有多大,请使用NumberFormat作为

double d = 2.102331119338414E156;
System.out.println(NumberFormat.getNumberInstance().format(d));

输出:

21023311193384140000000000000000000000000000000000000000000000000000000000000000000

因此,切换到BigDecimal应该会有所帮助。如果您随机生成ab值,请查看从给定范围生成随机BigDecimal值。

因此,通过科学记数法和数字的表示,让我们来看一个简化的形式。

a = -1.5E308    // round down*
b =  2.1E156
c =  0.2
d = a - b + (a * c)
d = -1.5E308 - 2.1E156 + (-1.5E308 * 0.2)
d = -1.5E308 - {insignificant*} + (-0.3E308)
d = -1.8E308   // under normal math ..

。。但是,64位IEEE 754 Double's(即double的存储格式)的范围为~[-1.79E308, 1.79E308],因为64位中只能存储这么多信息。

CCD_ 19的结果在该范围的之外。因此,它被表示为(负)无穷大。


*注意最初的四舍五入并丢弃不重要的值-这一结果保证为&lt-1.8E308,尽管可以更精确地计算。重点是这是在double的可表示范围之外的

使用BigDecimal之所以有效,是因为(输入是否为"随机"并不重要),因为它没有这个范围限制。

最新更新