Java Math立方根损失精度

时间:2013-11-02 16:15:35

标签: java

我对java比较陌生,所以对我很轻松,

我有函数g(x) = 8x^3

我必须在g之后输出g的倒数。所以:

inverseGAG = ((Math.pow(functionG, 1.0/3))/8);

它给了我几乎正确的答案,例如,让我说x = 4

g(4) = 512,因此512的逆G将是512的立方根,即8,然后我们除以8 = 1.

我的程序正在输出0.9999999999,我不明白为什么?

2 个答案:

答案 0 :(得分:1)

您期望从不精确的数字表示得到确切的答案。假设您使用的是double类型,那么在计算中只有64位可用于存储值。最重要的是,值存储在二进制(基数2)中,而不是十进制数(基数10),并且可以在这两个基数中精确表示的分数是不同的。例如,0.1 10 =0.00̅0̅1̅1̅ 2

由于可用的精度有限,当您进行浮点运算时,必然会出现舍入误差。如果您想了解浮点数学所涉及的更多细节,可以查看Introduction to Programming in Java, 9.1 Floating pointWhat Every Computer Scientist Should Know About Floating-Point Arithmetic

在您的情况下,切换到使用Math.cbrt可能会产生足够好的答案。更一般地说,做一些像舍入到10位小数的东西可能会给你一个足够好的答案 - 但是在所有情况下你都无法做出正确答案。

答案 1 :(得分:0)

其他注释是正确的,你不能指望浮点运算的精确结果,通常BigDecimal就是答案。但是,没有办法计算BigDecimal中数字的任何非整数幂,因为结果可能至少是无理的。所以这不是一个很好的答案。

我想强调Louis Wasserman的评论,这可能是最实际的答案。 Math.cbrt()会在这里提供更好的精确度,事实上你的论证会得到1.0。我想它在一个立方根的情况下使用牛顿方法的特化,这将比一般pow()方法提供更好的准确性,我期望使用对数。

当然也参见Math.sqrt()