Java中的大数字计算?
我有这个Java代码来计算一些数字Java中的大数字计算?,java,long-integer,biginteger,Java,Long Integer,Biginteger,我有这个Java代码来计算一些数字 import java.math.BigInteger; class Challenge { final static BigInteger THOUSAND = new BigInteger("1000"); private static BigInteger compute(long n) { BigInteger a = BigInteger.ONE; BigInteger b = BigIntege
import java.math.BigInteger;
class Challenge {
final static BigInteger THOUSAND = new BigInteger("1000");
private static BigInteger compute(long n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
for (long i = 0; i < n; i++) {
BigInteger next = b.multiply(b).add(a);
a = b;
b = next;
}
return b.mod(THOUSAND);
}
public static void main(String args[]) {
for (long n : new long[] { 1L, 2L, 5L, 10L, 20L, Long.MAX_VALUE }) {
System.out.print(n + " ---> ");
System.out.println(compute(n));
}
}
}
然后返回b mod 1000
,给出计算的最后3位数字
到目前为止,代码返回:
1 ---> 2
2 ---> 5
5 ---> 783
10 ---> 968
20 ---> 351
9223372036854775807 --->
在最后一次迭代中,代码继续工作,但如果迭代次数太大,则需要花费很长时间,因此永远无法完成
有没有办法更快地进行此类计算,或者以更好的方式获得所需的值(多次计算的mod 1000)?这个数字太大了。处理这个函数需要很长时间是正常的。 您可以尝试使用以下方法进行检查:
long startTime=System.currentTimeMillis();
……你的节目。。。。
long-endTime=System.currentTimeMillis();
长总时间=结束时间-开始时间;
系统输出打印项次(总时间);
完成计算的估计时间。是的,为每次计算保持运行moludo。您不需要计算所有数字,因为您只对最后3个数字感兴趣 第一个改进是具备以下功能:
private static BigInteger compute(long n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
for (long i = 0; i < n; i++) {
BigInteger next = b.multiply(b).add(a);
a = b;
b = next.mod(THOUSAND); // <-- only keep the modulo each time so as not calculate all digits
}
return b.mod(THOUSAND);
}
请注意,此代码仍然不会将
9223372036854775807
的结果作为输入。根本不可能循环9223372036854775807次。但是,在我的旧机器上,这会在5秒内生成1亿的正确结果。如果使用int
进行计算,速度会快得多。但是,如果您意识到在每次迭代中,a
和b
只有1000000个可能的起始值,则速度会更快,这意味着a
和b
不重复的最长可能值序列和结果为一百万。i、 e.您可以n%1000000
最有可能存在较短的重复序列
我之所以只说a
和b
的下三位数很重要,是因为你mod 1000
结果,所以不管a
和b
的上三位数是什么,它们都会被忽略,所以你只关心0
到999
你可以从1,1开始记住所有可能的结果,这只是一个查找
private static long compute(long n) {
int a = 1;
int b = 1;
for (int i = 0, max = (int) (n % 1000000); i < max; i++) {
int next = b * b + a;
a = b;
b = next % 1000;
}
return b % 1000;
}
专用静态长计算(长n){
INTA=1;
int b=1;
对于(int i=0,max=(int)(n%1000000);i
它真的需要在Long.MAX\u值下工作吗?如果是这样的话,忘记for
循环吧,你不可能循环9223372036854775807次。既然你最后在做mod 1000
,你也可以放弃biginger
,在每次迭代中都用1k修改整数。另外,您显然需要找到序列的周期。任何理智的人都不会要求你循环Long.MAX\u VALUE
次。据我所知,我需要做的是迭代到I
,而不是I
,对吗?我改了,看起来效果不错,号码是512。虽然我仍然不完全理解为什么a和b只有1000000个可能的起始值。1000000是函数的周期吗?@Julian只有a
和b
的较低3位才重要。其中最长的可能序列包括1000*1000的每个可能组合。重复序列可能较短,但应为1000000倍。
private static long compute(long n) {
int a = 1;
int b = 1;
for (long i = 0; i < n; i++) {
int next = b*b + a;
a = b;
b = next % 1000;
}
return b % 1000;
}
private static long compute(long n) {
int a = 1;
int b = 1;
for (int i = 0, max = (int) (n % 1000000); i < max; i++) {
int next = b * b + a;
a = b;
b = next % 1000;
}
return b % 1000;
}