我有一行代码添加了几个双精度数,它给出了无穷大的结果,而双精度数只是小而长的小数
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'和' b'每次运行都要改变
答案 0 :(得分:1)
正在发生溢出。表达式a - b + (a * c)
的结果大小大于最大可能double
,Double.MAX_VALUE
或1.7976931348623157E308
。发生这种情况时,结果是无穷大。由于a
为否定,因此会产生-Infinity
。
如果您将a
和b
的指数减少1
以查看结果,可以看到这一点:
-1.8440517085856795E307
在结果中再次增加指数1
会产生比最大可能幅度大的数量。
您仍然可以使用BigDecimal
s。
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)));
答案 1 :(得分:0)
小数点欺骗了你。要查看double
值实际有多大,请使用NumberFormat
作为
double d = 2.102331119338414E156;
System.out.println(NumberFormat.getNumberInstance().format(d));
输出:
2,102,331,119,338,414,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
因此,切换到BigDecimal
应该会有所帮助。如果您随机生成a
和b
值,请查看Generating random BigDecimal value from given range。
答案 2 :(得分:0)
所以,在scientific notation and large numbers represented开始的情况下,让我们看一下简化的表格。
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-bit IEEE 754 Double's - 这是double
存储的格式 - 范围为〜[-1.79E308, 1.79E308]
,因为只有这么多信息可以以64位存储。
-1.8E308
的结果是在此范围之外。因此它表示为(negative) Infinity。
* 注意初始向下舍入并丢弃无关紧要的值 - 结果保证<&lt; -1.8E308,虽然随意使用它可以更精确。关键是在外 double
的可表示范围。
使用BigDecimal是有效的,因为它没有这个范围限制,因此输入是“随机”并不重要。