简体   繁体   中英

Sum of all digits for a given Positive Number of type long in Java

I was wondering why the following code solutions based on the modulo operation do not work when moving from the int type to the long type.

For example given 111111111111L I would like to get returned 12L .

How can I achieve the same expected behaviour described at the following question (that is working only for int type values)? Sum of all digits for a given Positive Number

I am also focused on performance issues so I am looking for an efficient solution.

public static long sumTheDigitsVersion1(long inputValue){
    long sum = inputValue % 9L;
        if(sum == 0){
            if(inputValue > 0)
                return 9L;
        }
    return sum;
}

public static long sumTheDigitsVersion2(long inputValue){
    return inputValue - 9L * ((inputValue - 1L) / 9L);
}

Thanks

The solution does not work because it's a solution to a different problem, namely:

repeatedly add up the number's digits until you achieve an single-digit result.

In other words, it computes 111111111111 -> 12 -> 3 .

When you think about it, n % 9 cannot possibly return 12 (which is what you say you're expecting).

Recursive, efficient solution:

public static long digitSum(long n) {
    if (n == 0)
        return 0;
    return n%10 + digitSum(n/10);
}

About as efficient as you'll get it:

private static final int PART_SIZE = 1000;
private static final int[] digitSums = new int[PART_SIZE];
static {
    for (int i = 0; i < digitSums.length; i++) {
        for (int n = i; n != 0; n /= 10) digitSums[i] += n % 10;
    }
}

public static long digitSum(long n) {
    int sum = 0;
    do {
        sum += digitSums[(int)(n % PART_SIZE)];
    } while ((n /= PART_SIZE) != 0);
    return sum;
}

This may not be the most efficient option buts its the only one I can think of on the top of my head:

public static long getDigitalSum(long n){
    n = Math.abs(n); //This is optional, remove if numbers are always positive. NOTE: Does not filter Long.MIN_VALUE

    char[] nums = String.valueOf(n).toCharArray();
    long sum = 0;

    for(char i:nums){
        sum = sum + Integer.parseInt(String.valueOf(i)); //Can use Long.parseLong() too
    }

    return sum;
}

I came out with the following solution after some tests with different numbers comparing 3 different functions involving 3 different approaches:

  • toCharArray() and loops,
  • basic mathematical computations and loops,
  • recursion.

I compared the 3 different approaches according to their time dimension using System.nanoTime() .

public static long sumTheDigits(long currentIterationValue){

    long currentDigitValue;
    long sumOutputValue = 0;

    while(currentIterationValue != 0) {
        currentDigitValue = currentIterationValue % 10;
        currentIterationValue = currentIterationValue / 10;
        sumOutputValue = sumOutputValue + currentDigitValue;
    }
    return sumOutputValue;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM