Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Summing all digits of 2^1000

I'm trying to solve Project Euler problem #16, where I need to sum all the digits of 2^1000. I've gotten stuck dealing with such a big number. My program worked for any number below 10^16, but failed afterwards. This told me that my logic was correct. I went ahead and converted all variables and methods to BigDecimal, but now the program does not run properly. It compiles as it is and there is no error; it just does not terminate. Does anyone have an idea on where I went wrong here?

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Powerdigitsum {

    private static final BigDecimal one = new BigDecimal("1");
    private static final BigDecimal ten = new BigDecimal("10");

    private static BigDecimal sumofDigits(BigDecimal n){

        BigDecimal sum = new BigDecimal("0");

        while(n.compareTo(one) == 1 || n.compareTo(one) == 0){

            sum.add(n.remainder(ten));

            n.divide(ten);

            n = n.setScale(0, RoundingMode.FLOOR);

        }

    return sum;

    }

    public static void main(String[] args) {

        final double the_number = Math.pow(2,1000);

        final double test = 15;

        final BigDecimal two_to_the_thousandth_power = new BigDecimal(test);

        System.out.println(sumofDigits(two_to_the_thousandth_power));

    }

}
like image 892
Brian Avatar asked Dec 21 '22 11:12

Brian


2 Answers

Just use BigInteger properly:

BigInteger a = new BigInteger("2").pow(1000);

like image 182
mishadoff Avatar answered Dec 30 '22 07:12

mishadoff


The whole method is kinda wrong. See this:

private static BigInteger sumOfDigits(BigInteger n) {
    BigInteger sum = BigInteger.ZERO;
    while (n.compareTo(BigInteger.ZERO) == 1) {
        sum = sum.add(n.remainder(ten));
        n = n.divide(ten);
    }
    return sum;
}

You needed to compare to zero, not one. And you need to assign the values for BigIntegers and BigDecimals, their methods do nothing on their own, the instances of those classes are immutable.

For integers, it's generally better to use BigInteger. The decimal part (that gets there from dividing) is just thrown away.

like image 23
Petr Janeček Avatar answered Dec 30 '22 06:12

Petr Janeček