1

所以我正在编写一个程序来进行一些计算,但我注意到我没有得到预期的结果。

我正在使用 Math.acos() 和 Math.sqrt() 函数,当我期望得到零答案时,我得到的答案非常小,几乎为零。

> System.out.println(Math.acos(27441738 / (Math.sqrt(27441738)*Math.sqrt(27441738))));
1.4901161193847656E-8

这通常应该打印出 0.0。我在这里缺少什么吗?

4

1 回答 1

1

没有通用规则来缩小涉及浮点运算的表达式中的错误。

对于这种特殊情况,您可以使用分数合理化来大大减轻错误:

                                              -------------
        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 系统开始,向您介绍浮点运算的复杂概念。

于 2013-09-06T20:58:41.867 回答