所以我正在编写一个程序来进行一些计算,但我注意到我没有得到预期的结果。
我正在使用 Math.acos() 和 Math.sqrt() 函数,当我期望得到零答案时,我得到的答案非常小,几乎为零。
> System.out.println(Math.acos(27441738 / (Math.sqrt(27441738)*Math.sqrt(27441738))));
1.4901161193847656E-8
这通常应该打印出 0.0。我在这里缺少什么吗?
所以我正在编写一个程序来进行一些计算,但我注意到我没有得到预期的结果。
我正在使用 Math.acos() 和 Math.sqrt() 函数,当我期望得到零答案时,我得到的答案非常小,几乎为零。
> System.out.println(Math.acos(27441738 / (Math.sqrt(27441738)*Math.sqrt(27441738))));
1.4901161193847656E-8
这通常应该打印出 0.0。我在这里缺少什么吗?
没有通用规则来缩小涉及浮点运算的表达式中的错误。
对于这种特殊情况,您可以使用分数合理化来大大减轻错误:
-------------
x x 1 x 1 √x | x √x |
1 = -------- = --- * --- = --- * --- * --- = | --- * --- |
√x * √x √x √x √x √x √x | √x x |
-------------
评估新表达式(使用bsh
):
System.out.println( Math.acos( (27441738 / Math.sqrt(27441738)) * (Math.sqrt(27441738) / 27441738) ) );
印刷:
0.0
关于建议阅读的一件事,正如其他人指出的那样,获取有关 FP 的信息的一个很好的起点是“ What Every Computer Scientist Should Know About Floating-Point Arithmetic ”详细介绍了浮点运算,尽管我更喜欢计算机表示Numbers and Computer Arithmetic,它更简单,更具教学性,它甚至从一个玩具 fp 系统开始,向您介绍浮点运算的复杂概念。