我正在研究欧拉项目的问题29,其中指出:
考虑a ^ b的所有整数组合,2≤a≤5且2≤b≤5:
2 ^ 2 = 4,2 ^ 3 = 8,2 ^ 4 = 16,2 ^ 5 = 32
3 ^ 2 = 9,3 ^ 3 = 27,3 ^ 4 = 81,3 ^ 5 = 243
4 ^ 2 = 16,4 ^ 3 = 64,4 ^ 4 = 256,4 ^ 5 = 1024
5 ^ 2 = 25,5 ^ 3 = 125,5 ^ 4 = 625,5 ^ 5 = 3125
如果它们按数字顺序放置,删除任何重复,我们得到以下15个不同术语的序列:
4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125
ab生成的序列中有多少个不同的术语,2≤a≤100且2≤b≤100?
我已经编写了用Java解决这个问题的程序。它运行时没有任何错误,但是没有给出预期的输出。我在下面提供了我的代码和输出。
import java.util.ArrayList;
import java.math.BigInteger;
public class problemTwentyNine {
public static void main(String [] args) {
long start = System.nanoTime();
ArrayList<BigInteger> distinctTerms = new ArrayList<BigInteger>();
BigInteger temp;
for(int i = 2; i <= 100; i++) {
for(int j = 2; j <= 100; j++) {
temp = new BigInteger("" + (int) (Math.pow(i, j)));
if(!distinctTerms.contains(temp)) {
distinctTerms.add(temp);
}
}
}
System.out.println(distinctTerms.size());
long stop = System.nanoTime();
System.out.println("Execution time: " + ((stop - start) / 1e+6) + "ms");
}
}
输出:
422
执行时间:24.827827ms
在项目euler上输入此答案后,我们可以看到它是不正确的;但我无法看到我的代码出错了。
答案 0 :(得分:4)
(int) (Math.pow(i, j))
行没有多大意义,因为100^100
比Integer.MAX_VALUE
大得多。你应该使用BigInteger
来执行权力。
应该是
temp = BigInteger.valueOf(i).pow(j);
答案 1 :(得分:4)
您只获得422个不同元素的原因是您的值太大而且您将它们转换为int
。
当Math.pow(i, j)
(a double
)的结果大于Integer.MAX_VALUE
并且您投放到int
时,结果为Integer.MAX_VALUE
。< / p>
Section 5.1.3 of the JLS涵盖了缩小基元转换:
否则,以下两种情况之一必须为真:
值必须太小(大幅度或负无穷大的负值),第一步的结果是int或long类型的最小可表示值。
值必须太大(大幅度或正无穷大的正值),第一步的结果是最大可表示的类型int 或long。< / p>
(强调我的)
你得到的结果很多,所以只有422个不同的结果。
将您的计算更改为BigInteger
数学。
temp = new BigInteger("" + i).pow(j);
随着这一变化,我现在获得了9,183个不同的元素。这更有意义,因为一些完美正方形的力量将会重复。