Slugger
Slugger

Reputation: 675

Why doesnt this code for C to add the digits of a number not work?

I wrote this simple program to add the digits of a number k. The code is this:

#include<stdio.h>
#include<math.h>
int digitsum(int k)
{
    // This line will find the number of digits in k.
    int size = floor(log(k)/log(10))+1;
    int sum = 0, i, j;
    // Here I find the sum of digits starting with the leading digit.
    for (i=1;i<=size;i++)
    {
        j = floor(k*pow(10,-size+i)); // Leading digit
        sum = sum + j; // Add to sum
        k = k - j*pow(10,size-i); // Delete first digit
        //printf("%d   %d \n", j, k);
    }
    return sum;
}
main()
{
    int k =1141;
    int sum = digitsum(k);
    printf("%d", sum);
}

So sometimes my program works, for instance for k=141 it returns 6 but for k=1141 it also returns 6... I realize there is an easier way to do this task by taking the mod 10 and then dividing the number by 10. However I think this code should work. Any ideas what is going wrong? Thanks in advance. Also, I am just starting working with C, if there are any things that are not proper coding or rookie mistakes feel free to let me know. Thanks a lot!

Upvotes: 2

Views: 103

Answers (2)

chux
chux

Reputation: 153508

Suggest using round() rather than floor() when trying to convert double to int.

int size = round(log(k)/log(10)) + 1;

When the numeric result is just a tad below a whole number, floor() lops off the 0.999999999... fraction.


But round(log(k)/log(10)) as well as log10(k) fails when k is 0. A simple helper function would do:

int ilog10(int k) {
  if (k < 0) TBD();  // OP needs to clarify what to do when k < 0
  int sum = 1;
  while (k >= 10) {
    k /= 10;
    sum++;
  }
  return sum;
}

The solution to the larger problem could well follow @0xdeadbeef comment:

int digitsum(int k) {
  if (k < 0) TBD();  // OP needs to clarify what to do when k < 0
  int sum = 0;
  do {
    sum += k%10;
    k /= 10;
  } while (k > 0);
  return sum;
}

Upvotes: 2

Franz Holzinger
Franz Holzinger

Reputation: 998

You should take care of small rounding errors. Maybe this would help.

j = floor(k*pow(10,-size+i) + 0.000000001);

Upvotes: 1

Related Questions