47

What's the fastest and easiest to read implementation of calculating the sum of digits?

I.e. Given the number: 17463 = 1 + 7 + 4 + 6 + 3 = 21

Xn0vv3r
  • 17,766
  • 13
  • 58
  • 65

18 Answers18

112

You could do it arithmetically, without using a string:

sum = 0;
while (n != 0) {
    sum += n % 10;
    n /= 10;
}
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Beat me to it. This is the best way. – mmcdole Jan 26 '09 at 06:23
  • Personally, I see this better conceptually as a for loop... But maybe that's just my mind, I tend to see everything better as a for loop... – Matthew Scharley Jan 26 '09 at 08:04
  • 2
    @monoxide, the while loop is more succinct. You have no need for an index or for tight control of the loop iterations. – mmcdole Jan 26 '09 at 10:26
  • for (; n!= 0; n /= 10) { sum += n % 10;} To my mind there's an implicit counter there, n. But my mind is known to work funilly when talking about loops. There's no need to initialise n of course, because that's handled before the loop presumably. – Matthew Scharley Jan 26 '09 at 10:28
  • 1
    +1: I love this code, it's very elegant. Not new to me, but very cool. – Tom Chantler Sep 07 '11 at 07:22
  • how about is the number overflow? % or / won't work anymore! Try this code instead: n.ToString().Sum( c => Convert.ToInt32(c) ); – PerlDev Oct 06 '15 at 14:13
  • Okay, I know that % is modulus but can someone please fill me in on what on earth the `/=` means? I googled it but google does not understand what I am looking for. Thank you! EDIT: Never mind. += means add whatever is on the right to the variable on the left so /= must be the same but with division. DOH! All this time I did not know that! ( I knew you could do addition and subtraction but not division in this manner) – Hooplator15 Aug 24 '16 at 03:29
  • @JohnAugust: Although the following question is tagged [php], it answers your question: https://stackoverflow.com/questions/542995/what-is-used-for – Greg Hewgill Aug 24 '16 at 03:32
  • Thank you very much Greg, I still cannot believe I did not know that you could do that with division and multiplication. I always thought it was just addition and subtraction. – Hooplator15 Aug 24 '16 at 03:35
  • 1
    This assumes that the `n /= 10` will be truncated to an integer. For languages such as JavaScript, use something like `n = Math.floor(n / 10)` – caseyWebb Dec 09 '17 at 04:46
  • There are some cases that won't have reduced to a single digit by the time `n` reaches 0 (e.g. digit sum of 85 is 13). If it needs to always produce a single digit, I get around this by adding `|| sum > 9` to the while condition, and adding an if loop at the bottom (condition is `n == 0 && sum > 9`) that sets `n = sum` and `sum = 0` to restart the digit sum if it's not a single digit. Mathematically, this will always halt (there's no digit sum that will carry on producing long outputs). – Myles Apr 19 '20 at 13:09
  • Elegant approach, optimal solution, clean & short, easy to read, this is simply beautiful code. – Timothy Macharia Aug 05 '21 at 07:22
50

I use

int result = 17463.ToString().Sum(c => c - '0');

It uses only 1 line of code.

19

For integer numbers, Greg Hewgill has most of the answer, but forgets to account for the n < 0. The sum of the digits of -1234 should still be 10, not -10.

n = Math.Abs(n);
sum = 0;
while (n != 0) {
    sum += n % 10;
    n /= 10;
}

It the number is a floating point number, a different approach should be taken, and chaowman's solution will completely fail when it hits the decimal point.

Ants
  • 2,628
  • 22
  • 35
  • 1
    Good catch. It all depends on how the modulo operator is defined in the language in question; in C# the result takes the same sign as the dividend which makes my method fail for negative numbers. In other languages it may work, see the table at http://en.wikipedia.org/wiki/Modulo_operation – Greg Hewgill Jan 26 '09 at 08:04
14
 public static int SumDigits(int value)
 {
     int sum = 0;
     while (value != 0)
     {
         int rem;
         value = Math.DivRem(value, 10, out rem);
         sum += rem;
     }
     return sum;
 }
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Assuming DivRem does the intelligent thing, this should avoid doing the division twice. I like it better than the other obvious answer (though both are close). – Lawrence Dol Jan 26 '09 at 06:50
  • This is the code of DivRem public static int DivRem(int a, int b, out int result) { result = a % b; return (a / b); } so it does not make intelligent thing!! – Ahmed Jan 26 '09 at 07:50
  • Any reasonable compiler will see that x and y don't change between the x/y and x%y operations and thus can utilize a single divsion op to get both results. I know that gcc does this for c/c++ code. I assume c# compilers are at least as competent with such a simple optimization. – Evan Teran Jan 26 '09 at 08:03
  • This almost certainly isn't something the C# compiler would do - it would be up to the JIT. – Jon Skeet Jan 26 '09 at 08:22
  • 1
    fair enough, I was kinda lumping the JIT and the compiler proper into one category, but yea, the JIT would do the actual optimization. – Evan Teran Jan 26 '09 at 15:25
14
int num = 12346;
int sum = 0;
for (int n = num; n > 0; sum += n % 10, n /= 10) ;
Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131
3

I thought I'd just post this for completion's sake:

If you need a recursive sum of digits, e.g: 17463 -> 1 + 7 + 4 + 6 + 3 = 21 -> 2 + 1 = 3
then the best solution would be

int result = input % 9;
return (result == 0 && input > 0) ? 9 : result;
Nolonar
  • 5,962
  • 3
  • 36
  • 55
3

I like the chaowman's response, but would do one change

int result = 17463.ToString().Sum(c => Convert.ToInt32(c));

I'm not even sure the c - '0', syntax would work? (substracting two characters should give a character as a result I think?)

I think it's the most readable version (using of the word sum in combination with the lambda expression showing that you'll do it for every char). But indeed, I don't think it will be the fastest.

Brad Mace
  • 27,194
  • 17
  • 102
  • 148
Tjipke
  • 408
  • 3
  • 12
  • I come here 7 years late , but for some reason `Convert.ToInt32` returned `4 * 54 = 206` for me when I ran it with this code: `2156.ToString().Sum(c => Convert.ToInt32(c));` Any idea whats going on? c - '0' worked perfectly tho. – kuskmen Apr 12 '16 at 20:29
  • 1
    @kuskmen See https://msdn.microsoft.com/en-us/library/ww9t2871(v=vs.110).aspx ... the iterator of a string iterates over chars This invocation of ToInt32() returns a 32-bit signed integer that represents the UTF-16 encoded code unit of the value argument. – moreON Apr 15 '16 at 06:02
  • so I guess my improvement in 2009, was not really a working improvement :-( (So just ignore this answer) – Tjipke Jul 22 '16 at 09:33
  • 3
    `Math.Abs(-123).ToString().Sum(char.GetNumericValue);` – Slai Jan 14 '17 at 21:21
3
int n = 17463; int sum = 0;
for (int i = n; i > 0; i = i / 10)
{
sum = sum + i % 10;
}
Console.WriteLine(sum);
Console.ReadLine();
  • 1
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Isma Jan 05 '18 at 14:56
2

I would suggest that the easiest to read implementation would be something like:

public int sum(int number)
{
    int ret = 0;
    foreach (char c in Math.Abs(number).ToString())
        ret += c - '0';
    return ret;
}

This works, and is quite easy to read. BTW: Convert.ToInt32('3') gives 51, not 3. Convert.ToInt32('3' - '0') gives 3.

I would assume that the fastest implementation is Greg Hewgill's arithmetric solution.

sindre j
  • 4,404
  • 5
  • 31
  • 32
1
private static int getDigitSum(int ds)
{
    int dssum = 0;            
    while (ds > 0)
    {
        dssum += ds % 10;
        ds /= 10;
        if (dssum > 9)
        {                
            dssum -= 9;
        }
    }
    return dssum;
}

This is to provide the sum of digits between 0-9

Gangaraju
  • 4,406
  • 9
  • 45
  • 77
1
public static int SumDigits1(int n)
{
    int sum = 0;
    int rem;
    while (n != 0)
    {           
        n = Math.DivRem(n, 10, out rem);
        sum += rem;
    }
    return sum;
}

public static int SumDigits2(int n)
{
    int sum = 0;
    int rem;
    for (sum = 0; n != 0; sum += rem)   
        n = Math.DivRem(n, 10, out rem);        
    return sum;
}   

public static int SumDigits3(int n)
{
    int sum = 0;    
    while (n != 0)
    {
        sum += n % 10;
        n /= 10;
    }   
    return sum;
}   

Complete code in: https://dotnetfiddle.net/lwKHyA

gschuster
  • 98
  • 1
  • 8
0
int j, k = 1234;
for(j=0;j+=k%10,k/=10;);
0

A while back, I had to find the digit sum of something. I used Muhammad Hasan Khan's code, however it kept returning the right number as a recurring decimal, i.e. when the digit sum was 4, i'd get 4.44444444444444 etc. Hence I edited it, getting the digit sum correct each time with this code:

 double a, n, sumD;
 for (n = a; n > 0; sumD += n % 10, n /= 10);
 int sumI = (int)Math.Floor(sumD);

where a is the number whose digit sum you want, n is a double used for this process, sumD is the digit sum in double and sumI is the digit sum in integer, so the correct digit sum.

0
static int SumOfDigits(int num)
{
    string stringNum = num.ToString();
    int sum = 0;
    for (int i = 0; i < stringNum.Length; i++)
    {
      sum+= int.Parse(Convert.ToString(stringNum[i]));

    }
    return sum;
}
johnny 5
  • 19,893
  • 50
  • 121
  • 195
0

If one wants to perform specific operations like add odd numbers/even numbers only, add numbers with odd index/even index only, then following code suits best. In this example, I have added odd numbers from the input number.

using System;
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine("Please Input number");
        Console.WriteLine(GetSum(Console.ReadLine()));
    }
    
    public static int GetSum(string num){
        int summ = 0;
        for(int i=0; i < num.Length; i++){
            int currentNum;
            if(int.TryParse(num[i].ToString(),out currentNum)){
                 if(currentNum % 2 == 1){
                    summ += currentNum;
                }
            }
       } 
       return summ;
    }
}
Tejas
  • 39
  • 1
  • The original question does not ask to sum the odd digits. Please, consider updating your answer to provide a solution to the original question. – Brent Worden Jul 05 '20 at 20:07
-1

The simplest and easiest way would be using loops to find sum of digits.

int sum = 0;
int n = 1234;

while(n > 0)
{
    sum += n%10;
    n /= 10;
}
Pankaj Prakash
  • 2,300
  • 30
  • 31
-1
#include <stdio.h>

int main (void) {

    int sum = 0;
    int n;
    printf("Enter ir num ");
    scanf("%i", &n);

    while (n > 0) {
        sum += n % 10;
        n /= 10;
    }

    printf("Sum of digits is %i\n", sum);

    return 0;
}
DanielBarbarian
  • 5,093
  • 12
  • 35
  • 44
-2

Surprised nobody considered the Substring method. Don't know whether its more efficient or not. For anyone who knows how to use this method, its quite intuitive for cases like this.

string number = "17463";
int sum = 0;
String singleDigit = "";
for (int i = 0; i < number.Length; i++)
{
singleDigit = number.Substring(i, 1);
sum = sum + int.Parse(singleDigit);
}
Console.WriteLine(sum);
Console.ReadLine();
cricketycrack
  • 57
  • 1
  • 4