我正在研究一个基本上是斐波那契序列的问题陈述:
给定两个初始值作为输入,计算项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
为什么我长时间遇到这种精度损失,如何防止它/得到我想要的输出?
答案 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;
}
}
}