警告浮点数
Caveat floating point
我需要找到三个 Double 类型的值 x、y、z,使得 (x + y) + z == 1.0 和 x + (y + z) == 0.0。我试图在 Scala 上解决这个问题。这个问题与 Is floating point math broken? 有关,但我应该如何找到这样的值?有什么算法可以完成这个任务吗?据我所知,如果分母是 2 的幂,则它会无误地转换为浮点数。我尝试了 0.5、1、0、0.25 之类的值仍然没有成功。谁能帮帮我?
使用正确的 x、y 和 z 值,可以准确地获得 1.0 和 0.0,而无需在比较中使用 epsilon。我在 Java 中编写了我的程序,但该原则将适用于其他使用 IEEE 754 64 位二进制浮点数作为 Double 的语言。
public class Test {
public static void main(String[] args) {
double x = -Math.pow(2.0, 53);
double y = 1.0;
double z = -x;
System.out.println((x + y) + z == 1.0);
System.out.println(x + (y + z) == 0.0);
}
}
[-Math.pow(2.0, 53), Math.pow(2.0, 53)]
是所有整数值都可以精确表示的双精度范围。在该范围之外,所有奇数都必须四舍五入。将两端的幅度增加 1 需要四舍五入,四舍五入甚至回到它自己。
x + y
,符号相反,在范围内,可以精确表示。将 z
添加到结果得到 1.0,即加法的实数结果。另一方面,y + z
具有等号,使得奇数的大小太大而无法精确表示,因此它四舍五入为 z
,加上 x
结果为 0.0.
我需要找到三个 Double 类型的值 x、y、z,使得 (x + y) + z == 1.0 和 x + (y + z) == 0.0。我试图在 Scala 上解决这个问题。这个问题与 Is floating point math broken? 有关,但我应该如何找到这样的值?有什么算法可以完成这个任务吗?据我所知,如果分母是 2 的幂,则它会无误地转换为浮点数。我尝试了 0.5、1、0、0.25 之类的值仍然没有成功。谁能帮帮我?
使用正确的 x、y 和 z 值,可以准确地获得 1.0 和 0.0,而无需在比较中使用 epsilon。我在 Java 中编写了我的程序,但该原则将适用于其他使用 IEEE 754 64 位二进制浮点数作为 Double 的语言。
public class Test {
public static void main(String[] args) {
double x = -Math.pow(2.0, 53);
double y = 1.0;
double z = -x;
System.out.println((x + y) + z == 1.0);
System.out.println(x + (y + z) == 0.0);
}
}
[-Math.pow(2.0, 53), Math.pow(2.0, 53)]
是所有整数值都可以精确表示的双精度范围。在该范围之外,所有奇数都必须四舍五入。将两端的幅度增加 1 需要四舍五入,四舍五入甚至回到它自己。
x + y
,符号相反,在范围内,可以精确表示。将 z
添加到结果得到 1.0,即加法的实数结果。另一方面,y + z
具有等号,使得奇数的大小太大而无法精确表示,因此它四舍五入为 z
,加上 x
结果为 0.0.