对大整数的数字求和

4

我试图找到数字2^1000的各位数字之和,我正在使用Java BigInteger类来实现。然而,我无法实现它。最终,我用以下代码得到了0(零)。可能是什么问题?

谢谢...


在Kon的帮助下,我解决了问题,但这次我得到了错误的结果。有人能看出算法的问题吗?

public static void main(String []args) throws Exception
{
    BigInteger big = BigInteger.valueOf(2).pow(1000);
    BigInteger big2 = BigInteger.valueOf(0);


    //System.out.println(big);

    for(long i = 1; i<283; i++)
    {
         big2 = big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));
    }

    System.out.println(big2);
}
2个回答

3

试图使用 mod 计算每个 BigInteger 数字不是非常高效的,因为在此过程中你进行了许多方法调用。相反,你可以通过将其转换为 String 并立即获取每个数字来简化这个过程。

BigInteger big = BigInteger.valueOf(2).pow(1000);
String digits = big.toString();
int sum = 0;

for(int i = 0; i < digits.length(); i++) {
    int digit = (int) (digits.charAt(i) - '0');
    sum = sum + digit;
}

System.out.println(sum);

谢谢,我不知道我们可以这么容易地将BigInteger转换为String。我认为你的方法是最好的。但是我仍然想知道使用BigInteger进行运算的问题。因为当我检查2^10和2^15时,我的代码给出了正确的结果。如果你有时间并看一下并与我分享你的评论,我会很高兴。 - Özgür Devrim Arikan
1
看起来你正在达到 long 的极限,这是你在计算的中间步骤中使用的。在第20位数字之后,在 a.divide(b) 部分的 ab 操作数停止改变。尝试进行调试或打印出单独的结果,你就会明白我的意思。 - Warlord
我完全明白你的意思。感谢你的帮助。 - Özgür Devrim Arikan

1

BigInteger类是不可变的,因此您必须将操作的结果分配给变量本身。

big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));

应该变成

big2 = big2.add(big.mod(BigInteger.valueOf((long) Math.pow(10,i))).divide(BigInteger.valueOf((long)Math.pow(10,i-1))));

如果想了解Java中的不可变对象,请查看此文档

另外,虽然您的问题并非特别涉及此事,但在循环中使用硬编码文字值是非常糟糕的做法。您要循环遍历BigInteger 2^1000中的每个数字。那么,您可以使用类似于big.toString().length()的方法来获取数字的位数。


非常感谢!它修复了问题。但是这次似乎我的算法不正确,因为我得到了错误的答案。 - Özgür Devrim Arikan
@ÖzgürDevrimArikan 我会先创建一些示例程序,并创建一些显式的 BigInteger 值,例如“1234”。然后尝试循环遍历这些数字并查看发生了什么。请记住,一旦您获得了 2^1000 的 BigInteger 值,您可以将其作为字符串获取(请参见我的答案),然后在字符串的数字上循环非常容易,并且有数十个关于如何执行此操作的 SO 答案。 - Kon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接