tags:

views:

281

answers:

8

I've have a 5 digit integer say, int num = 23456

how to find the sum of the digits.???

+13  A: 

Use the modulo operation to get the value of the least significant digit:

int num = 23456;
int total = 0;
while (num != 0) {
    total += num % 10;
    num /= 10;
}

If the input could be a negative number then it would be a good idea to check for that and invert the sign.

Mark Byers
@Mark. Thank you.. This is what I was looking for.
Josh
I'm not actually that big a fan of things like `while (num)` unless `num` is an actual boolean-type value. I think it's more readable (and just as efficient unless your compiler is brain-dead) to use `if (num != 0)`. I don't dislike it enough to downvote a correct answer of course, it's just I haven't had my rant for today and, as pathetically understated as that rant was, it will have to do :-)
paxdiablo
@paxdiablo: Fixed. :)
Mark Byers
Oh, I didn't actually expect you to "fix" it since it's just a pet foible of mine. So +1 for being so gracious :-)
paxdiablo
I'm not really a fan of useless comparisons against 0. The C idiom is that `while (foo)` means "while foo is non-zero" should be universally understood by anyone who claims to know C and is just as readable. BTW, should we start writing `while (...(((num!=0)!=0)!=0...!=0)`???
R..
`do { total += num % 10; } while (num /= 10);` >:)
jnylen
@jnylen: elegant, but it performs an extra unnecessary modulo operation and division if `num` is 0 to begin with. Testing `num` first is more efficient.
R..
+3  A: 
int sum=0;while(num){sum+=num%10;num/=10;}

Gives a negative answer if num is negative, in C99 anyway.

Is this homework?

tc.
@tc. Thanks u. Not homework, lost touch with coding so learning C again.
Josh
This is more along the lines of basic math algorithms than C.
R..
+4  A: 
#include <stdio.h>

int main()
{
    int i = 23456;
    int sum = 0;

    while(i)
    {
        sum += i % 10;
        i /= 10;
    }

    printf("%i", sum);

    return 0;
}
Hamid Nazari
@Hamid. Thanks much.
Josh
@Josh no worries mate.
Hamid Nazari
+3  A: 

How about this:

for(sum=0 ,num=23456;num; sum+=num %10, num/=10);
Prasoon Saurav
@Prasoon. Thanks man. How does the logic for this go like???And can the sum of the digits be calculated without any control statements.
Josh
The logic is similar to Mark Byers' answer's logic. `And can the sum of the digits be calculated without any control statements` And why would anyone want to do that?
Prasoon Saurav
@Prasoon. Thank you. I just wanna try it in different ways..
Josh
@Prasoon. Sounds a bit crazy but true.
Josh
If you have a bound on the number, there's probably a nice multiplication trick to get the sum of the digits without any control statements.
R..
+2  A: 

If you want a way to do it without control statements, and incredibly efficient to boot, O(1) instead of the O(n), n = digit count method:

int getSum (unsigned int val) {
    static int lookup[] = {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, //     0-    9
         1,  2,  3,  4,  5,  6,  7,  8,  9, 10, //    10-   19
         2,  3,  4,  5,  6,  7,  8,  9, 10, 11, //    20-   29
         :
         9, 10, 11, 12, 13, 14, 15, 16, 17, 18, //    90-   99
         :
        14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // 23450-23459
        ::
    };
    return lookup[23456];
}

:-)

paxdiablo
Unfortunately it's `O(2^n)` in space. ;-)
R..
+1  A: 

Slightly related: if you want the repeated digit sum, a nice optimization would be:

if (num%3==0) return (num%9==0) ? 9 : 3;

Followed by the rest of the code.

R..
A: 

Actually, I answered with another (somewhat humorous) answer which used a absolutely huge array for a table lookup but, thinking back on it, it's not that bad an idea, provided you limit the table size.

The following functions trade off space for time. As with all optimisations, you should profile them yourself in the target environment.

First the (elegant) recursive version:

unsigned int getSum (unsigned int val) {
    static const unsigned char lookup[] = {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, //   0-  9
         1,  2,  3,  4,  5,  6,  7,  8,  9, 10, //  10- 19
         2,  3,  4,  5,  6,  7,  8,  9, 10, 11, //  20- 29
         :
        18, 19, 20, 21, 22, 23, 24, 25, 26, 27  // 990-999
    };
    return (val == 0) ? 0 : getSum (val / 1000) + lookup[val%1000];
}

It basically separates the number into three-digit groupings with fixed lookups for each possibility. This can easily handle a 64-bit unsigned value with a recursion depth of seven stack frames.

For those who don't even trust that small amount of recursion (and you should, since normal programs go that deep and more even without recursion), you could try the iterative solution:

unsigned int getSum (unsigned int val) {
    static const unsigned char lookup[] = {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, //   0-  9
         1,  2,  3,  4,  5,  6,  7,  8,  9, 10, //  10- 19
         2,  3,  4,  5,  6,  7,  8,  9, 10, 11, //  20- 29
         :
        18, 19, 20, 21, 22, 23, 24, 25, 26, 27  // 990-999
    };
    unsigned int tot = 0;
    while (val != 0) {
        tot += lookup[val%1000];
        val /= 1000;
    }
    return tot;
}

These are probably three times faster than the one-digit-at-a-time solution, at the cost of a thousand bytes of data. If you're not adverse to using 10K or 100K, you could increase the speed to four or five times but you may want to write a program to generate the static array statement above :-)

As with all optimisation options, measure, don't guess!

I prefer the more elegant recursive solution myself but I'm also one of those types who prefer cryptic crosswords. Read into that what you will.

paxdiablo
Stack frames hit memory. Lookup tables need to be cached to be efficient, and then they eat your cache. A sufficiently smart compiler might notice that recursion in this case is equivalent to iteration, but it's unlikely since your implementation isn't even tail-recursive. Prefer small code, so you don't eat your I-cache.
tc.
A: 
   #include <stdio.h>
  2 #include <stdlib.h>
  3
  4 #define BUFSIZE 20
  5
  6 int main(void)
  7 {
  8         int     number = 23456;
  9         char    myBuf[BUFSIZE];
 10         int     result;
 11         int     i = 0;
 12
 13         sprintf(myBuf,"%i\0",number);
 14
 15         for( i = 0; i < BUFSIZE && myBuf[i] != '\0';i++)
 16         {
 17                 result += (myBuf[i]-48);
 18         }
 19
 20         printf("The result is %d",result);
 21         return 0;
 22 }
 23

Another idea here using the sprintf and the ascii number representation

isioutis