java 是否做了一些舍入以避免 IEEE-754 表示中的不精确
Does java do some round off to avoid imprecision in IEEE-754 representation
我最近遇到了一个问题,我不得不考虑表示浮点数的不精确性。但令我惊讶的是,我没有发现我预期的错误。我创建了一个简单的示例代码来描述我的问题
public class Main {
public static void main(String[] args) {
float one_point_six = 1.6f; // According to IEEE-754, should be 1.60000002384185791015625
float zero_point_four = 0.4f; // According to IEEE-754, should be 0.4000000059604644775390625
float sum = one_point_six + zero_point_four; // shouldn't this be 2.0000000298023223876953125?
System.out.println(Math.ceil(sum)); // Prints 2.0. Shouldn't this be 3?
System.out.println(sum > 2f); // Prints false. Why?
}
}
即使我将浮点数替换为双精度数,输出仍然相同。 Java 是在进行四舍五入还是我遗漏了什么?
我使用 https://www.h-schmidt.net/FloatConverter/IEEE754.html 找出正在存储的“实际”值。
shouldn't this be 2.0000000298023223876953125?
没有。如您所知,float
的精度有限,因此它不够精确以存储该精度的数字。尝试使用您的转换器,并在其中输入 2.0000000298023223876953125,您会发现实际存储的值只是“2”。
我最近遇到了一个问题,我不得不考虑表示浮点数的不精确性。但令我惊讶的是,我没有发现我预期的错误。我创建了一个简单的示例代码来描述我的问题
public class Main {
public static void main(String[] args) {
float one_point_six = 1.6f; // According to IEEE-754, should be 1.60000002384185791015625
float zero_point_four = 0.4f; // According to IEEE-754, should be 0.4000000059604644775390625
float sum = one_point_six + zero_point_four; // shouldn't this be 2.0000000298023223876953125?
System.out.println(Math.ceil(sum)); // Prints 2.0. Shouldn't this be 3?
System.out.println(sum > 2f); // Prints false. Why?
}
}
即使我将浮点数替换为双精度数,输出仍然相同。 Java 是在进行四舍五入还是我遗漏了什么? 我使用 https://www.h-schmidt.net/FloatConverter/IEEE754.html 找出正在存储的“实际”值。
shouldn't this be 2.0000000298023223876953125?
没有。如您所知,float
的精度有限,因此它不够精确以存储该精度的数字。尝试使用您的转换器,并在其中输入 2.0000000298023223876953125,您会发现实际存储的值只是“2”。