如果你问我的话,下面这个例子给我的输出是非常奇怪的。这怎么可能?有没有办法把这两个值加起来?sum(float a,float b)也给出了相同的结果。
import java.text.DecimalFormat;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Sum: " + new DecimalFormat("#").format((1500036225984102400.f + 2000000000.f)));
}
}
输出为:
金额:1500036225984102400
当然我希望这两个值相加,但是第二个值似乎被忽略了?
2条答案
按热度按时间zsbz8rwp1#
如果您看看float是如何设置的(ieee-754),您很快就会发现尾数只有23位(实际上是24位,对于非规范化的数字,一位是隐式的)。
1500036225984102400为十六进制
所以你看,你的数字中非空的部分适合这24位。这就是为什么你得到的数字打印完全一样,你给它。任何进一步的位将被简单地切断(类似于整数除法,尽管在细节上并不完全相同)。实际上,这是数学上的四舍五入。
如果你现在比较一下你的两个数字:
您很快就会看到,加法的结果将不适合可用的24位,不适合的部分将被简单地四舍五入-正是您尝试添加的数字。。。
这通常是浮点数的一个问题,但是在double中不太常见,因为尾数和指数在那里更大。。。
utugiqy62#
浮点数的精度是有限的。您可以使用
Math.nextUp
方法。例如,可以使用以下方法查找比第一个操作数大的下一个最大数:您可以通过减法或使用
Math.ulp
,它告诉您“最后一个位置的单位”的大小,如果调整最低有效位,则数字增加的量:你会发现这个数字比
2000000000.f
:因此你的两个数字之和不能用一个更精确的数字来表示
float
比1500036225984102400.f
.