0

I am coming to SO as a last resort. Been trying to debug this code for the past 2 hours. If the question is suited to some other SE site, please do tell me before downvoting.

Here it goes:

#include <stdio.h>
#include<math.h>

int reverse(int n) {
    int count = 0, r, i;
    int k = (int)log(n * 1.0);
    for(i = k; i >= 0; i--)
    {
        r = (n % 10);
        n = (n / 10);
        count = count + (r * pow(10, k));
    }
    return count;
}

int main(void) {
     int t;
     scanf("%d", &t);

     while(t--)
     {
         int m, n, res;
         scanf("%d %d", &m, &n);
         res = reverse(m) + reverse(n);
         printf("%d", reverse(res));
     }
     return 0;
}

My objective is to get 2 numbers as input, reverse them, add the reversed numbers and then reverse the resultant as well.I have to do this for 't' test cases.

The problem: http://www.spoj.com/problems/ADDREV/

Any questions, if the code is unclear, please ask me in the comments. Thank you.

EDIT: The program gets compiled successfully. I am getting a vague output everytime. suppose the 2 numbers as input are 24 and 1, I get an output of 699998. If I try 21 and 1, I get 399998.

mch
  • 9,424
  • 2
  • 28
  • 42
Karan Singh
  • 1,114
  • 1
  • 13
  • 30
  • What is the problem with the code you have? For some example input, what is the expected and actual output? Do you get build errors? Run-time errors or crashes? Something else? And please take some time to [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). – Some programmer dude Jan 31 '17 at 12:49
  • You fail to state what your actual problem is. For example, is it related to how the numbers are being read? Looking at your scanf, you are not accounting for whitespace/newlines in the first read and in every other read after that. – David Hoelzer Jan 31 '17 at 12:49
  • @DavidHoelzer Using the `"%d"` format when reading input with `scanf` (and friends) discards leading white-space. – Some programmer dude Jan 31 '17 at 12:50
  • 3
    You say you have been trying to debug it? *How* have you done it? Have you tried to step through the code in a debugger? For input such as the one you show, does the `reverse` function give the correct result for `m` and `n`? What is the value or `res`? Also note that you print values in a loop *without spaces between* the values? Could that be a source of your problem? – Some programmer dude Jan 31 '17 at 12:51
  • Sorry for the inconvenience, I have edited the question. – Karan Singh Jan 31 '17 at 12:52
  • 1
    What does, say, `log(98*1.0)` return, and what do you expect it to return? – Mark Plotnick Jan 31 '17 at 13:01
  • I expect it to return a decimal greater than 1 but less than 2, something like 1.995.... – Karan Singh Jan 31 '17 at 13:02

3 Answers3

3

Okay, if you had properly debugged your code you would have notices strange values of k. This is because you use log which

Computes the natural (base e) logarithm of arg.

(took from linked reference, emphasis mine).

So as you are trying to obtain the 'length' of the number you should use log10 or a convertion (look at wiki about change of base for logarithms) like this: log(x)/log(10) which equal to log10(x)

And now let's look here: pow(10, k) <-- you always compute 10^k but you need 10^i, so it should be pow(10, i) instead.

Edit 1: Thanks to @DavidBowling for pointing out a bug with negative numbers.

I don't know how exactly you have to deal with negative numbers but here's one of possible solutions:

  1. before computing k:

    bool isNegative = n < 0; n = abs(n);

  2. Now your n is positive due to abs() returning absolute value. Go on with the same way.

  3. After for loop let's see if n was negative and change count accordingly:

    if (isNegative) { count = -count; } return count;

Note: Using this solution we reverse the number itself and leave the sign as it is.

Yuriy Ivaskevych
  • 956
  • 8
  • 18
  • thank you so much. I had just figured out the second error. I wish I could upvote your answer twice. – Karan Singh Jan 31 '17 at 13:13
  • 1
    The OP's code will run into problems for non-positive integers. – ad absurdum Jan 31 '17 at 13:24
  • @DavidBowling thanks for the tip! I've edited and fixed my answer. – Yuriy Ivaskevych Jan 31 '17 at 13:40
  • 1
    Good... but `log(0)` is also undefined. The C `log` functions return negative infinity for zero arguments and set `errno`. (They may also signal overflow for floating point arguments very close to zero). You can set `errno` to `0` before calling the `log()` function, and check it after. – ad absurdum Jan 31 '17 at 13:48
  • @DavidBowling from [docs](http://en.cppreference.com/w/c/numeric/math/log10): `If the argument is ±0, -∞ is returned and FE_DIVBYZERO is raised.`. So `k` would be -infinity and the loop never enters, so 0 is returned (`count` is initialized). This is not the best option because we need to check that `FE_DIVBYZERO` and probably reset `errno` – Yuriy Ivaskevych Jan 31 '17 at 13:58
  • A closer look at the C Standard reveals that these functions are not required to return signed infinities, or even nan (C11 §7.12.1 3). The return value is implementation defined for a pole error. It is better to check for errors, though for `log()` Standard says "A pole error _may_ occur if the argument is zero." Better yet to simply test for `n == 0` and return `0` in this case. – ad absurdum Jan 31 '17 at 14:58
1

It looks like Yuri already found your problem, but might I suggest a shorter version of your program? It avoids using stuff like log which might be desirable.

#include <stdio.h>

int rev (int n) {
    int r = 0;
    do {
        r *= 10;
        r += n % 10;
    } while (n /= 10);
    return r;
}

int main (void) {
    int i,a,b;
    scanf("%d",&i);

    while (i--) {
        scanf("%d %d",&a,&b);
        printf("%d\n",rev(rev(a) + rev(b)));
    }       
    return 0;
}

Hopefully you can find something useful to borrow! It seems to work okay for negative numbers too.

Micrified
  • 3,338
  • 4
  • 33
  • 59
0

Under the hood you get char string, reverse it to numeric, than reverse it to char. Since is more comfortable work with chars than let's char:

char * reverse (char *s,size_t len) //carefull it does it in place
{
   if (!len) return s; 
   char swp, *end=s+len-1;
   while(s<end)
   {
       swp =*s;
       *s++=*end;
       *end--=swp; 
   } 
   return s;
}
void get_num(char *curs)
{
     char c;
     while((c=getchar())!='\n')
      *curs++=c;
     *curs=0;
}
int main()
{
     double a,b,res;
     char sa[20],sb[20],sres[20],*curs;
     get_num( sa);
     get_num(sb);
     reverse(sa,strlen(sa));
     reverse(sb,strlen(sb));
     sscanf(sa,"%f",&a);
     sscanf(sb,"%f",&b);
     res=a+b;
     sprintf(sres,"%f",res);
     reverse(sres);
     printf(sres);

 }
jurhas
  • 613
  • 1
  • 4
  • 12