Java 为什么不';两个浮点值的正确求和不总是有效的吗?

Java 为什么不';两个浮点值的正确求和不总是有效的吗?,java,types,sum,Java,Types,Sum,如果你问我的话,下面的例子给出的输出非常奇怪。这怎么可能呢?有没有办法将这两个值正确相加?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((150003622

如果你问我的话,下面的例子给出的输出非常奇怪。这怎么可能呢?有没有办法将这两个值正确相加?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


当然,我希望这两个值相加,但第二个值似乎被忽略了?

浮点数的精度是有限的。您可以使用该方法找到可表示的下一个最大数字。例如,可以使用以下命令查找第一个操作数以外的下一个最大数:

float next = Math.nextUp(1500036225984102400.f);
您可以通过减法或使用来获得某个数字与其下一个最大数字之间的跳转大小,这会告诉您“最后一位的单位”的大小,如果调整最低有效位,则该数字将增加的量:

float ulp = Math.ulp(1500036225984102400.f);
您会发现这个数字大于
2000000000.f

Math.ulp(1500036225984102400.f) = 137438953472.0
                                    2000000000.0

因此,用
浮点数表示两个数字之和不能比
1500036225984102400更精确。f
浮点数具有有限精度。您可以使用该方法找到可表示的下一个最大数字。例如,可以使用以下命令查找第一个操作数以外的下一个最大数:

float next = Math.nextUp(1500036225984102400.f);
您可以通过减法或使用来获得某个数字与其下一个最大数字之间的跳转大小,这会告诉您“最后一位的单位”的大小,如果调整最低有效位,则该数字将增加的量:

float ulp = Math.ulp(1500036225984102400.f);
您会发现这个数字大于
2000000000.f

Math.ulp(1500036225984102400.f) = 137438953472.0
                                    2000000000.0

因此,用
浮点数
表示两个数字之和不能比
1500036225984102400更精确。f

如果查看浮点数是如何设置的(),您很快就会发现尾数只有23位(实际上是24位,一位对于非标准化数字是隐式的)

1500036225984102400为十六进制14 d1 3300 14 d1 33 00 00 00 00 00 所以你看,你的数字中非空的部分适合这24位。这就是为什么你得到的数字打印完全一样,你给它。任何进一步的位都将被简单地截断(类似于整数除法,尽管在细节上并不完全相同)。实际上,这是数学上的四舍五入

因此,如果您现在比较两个数字: 14 d1 33 00 00 00 00 00 77 35 94 00 14 d1 3300 77 35 9400您很快就会发现加法的结果与可用的24位不符,而不符的部分会被简单地四舍五入-正是您尝试添加的数字


这通常是浮点数的问题,但使用double时不太常见,因为尾数和指数在那里只是更大而已…

如果您查看浮点数是如何设置的(),您很快就会发现尾数只有23位(实际上是24位,一位对于非规范化数字是隐式的)

1500036225984102400为十六进制14 d1 3300 14 d1 33 00 00 00 00 00 所以你看,你的数字中非空的部分适合这24位。这就是为什么你得到的数字打印完全一样,你给它。任何进一步的位都将被简单地截断(类似于整数除法,尽管在细节上并不完全相同)。实际上,这是数学上的四舍五入

因此,如果您现在比较两个数字: 14 d1 33 00 00 00 00 00 77 35 94 00 14 d1 3300 77 35 9400您很快就会发现加法的结果与可用的24位不符,而不符的部分会被简单地四舍五入-正是您尝试添加的数字

这通常是浮点数的一个问题,但使用double时不太常见,因为尾数和指数在那里更大