精度损失乘以大长度

时间:2014-10-04 02:55:31

标签: java double long-integer

我正在研究一个基本上是斐波那契序列的问题陈述:

给定两个初始值作为输入,计算项x =(项x-1)^ 2 +(项x-2)

因此,给定输入0 1 5,我们想要计算序列的第5项,这是通过以下方式完成的:

第3项=(第2项)^ 2 +(第1项)= 1 ^ 2 + 0 = 1

第4项=(第3项)^ 3 +(第2项)= 1 ^ 1 + 1 = 2

第5项= 2 ^ 2 + 1 = 5

等等。

当我尝试计算一个大值时,我的问题就出现了,比如10号。使用long作为我的数据类型,我精确地丢失了第10个值。预期/正确的值是'84266613096281243382112,但我得到..

0 1 10
Term number 3 has value 1
Term number 4 has value 2
Term number 5 has value 5
Term number 6 has value 27
Term number 7 has value 734
Term number 8 has value 538783
Term number 9 has value 290287121823
Term number 10 has value 1886167576011600224

使用double作为我的数据类型执行相同的问题会给我正确的答案,但不是我需要的格式(这是针对自动化测试用例)。

0 1 10
Term number 3 has value 1.0
Term number 4 has value 2.0
Term number 5 has value 5.0
Term number 6 has value 27.0
Term number 7 has value 734.0
Term number 8 has value 538783.0
Term number 9 has value 2.90287121823E11
Term number 10 has value 8.426661309628124E22

为什么我长时间遇到这种精度损失,如何防止它/得到我想要的输出?

2 个答案:

答案 0 :(得分:1)

那是因为long's max value is 2^63-1(或9.223372e + 18)。你根本不能高于此。

如果double对于您的应用程序具有足够的精确度,您可以查看根据规范对其进行格式化,例如DecimalFormat

如果double不够精确,您可以查看使用BigInteger。但它会带来更高的性能成本。

答案 1 :(得分:1)

尝试使用BigInteger类,它可以工作:

import java.math.BigInteger;

public class Test {

    public static void main(String[] args) {
        BigInteger x1, x2, x3;

        x1 = new BigInteger("0");
        x2 = new BigInteger("1");

        for (int i = 3; i <= 10; i++){
            x3 = x2.multiply(x2).add(x1);
            System.out.println(i + ":" + x3);
            x1 = x2;
            x2 = x3;
        }
    }

}