-1

Currently new to C and took up the exercise to reverse a number using a temporary variable. The code goes as follows:

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


int main(){
    int a, length=1, rem, temp;
    printf("Enter number to be reversed: ");
    scanf("%d",&a);

    /* calculating length of number */
    while (1){
        if (a/(int)pow(10,length)==0){
            break;
        }
        else{
            length++;
        }
    }
    printf("%d\n", length);

    /* reversing logic */
    for (int i= 1; i <= length; i++){
        rem = a%10;
        temp += rem*(pow(10,(length-i)));
        a /= 10;
    }

    printf("%d\n",temp);
    return 0;
}

The problem is that the parts 'calculating length of number' and 'reversing logic' work perfectly fine independently but the later one breaks down and return some -ve number when the aforementioned code is executed. The former parts executes perfectly returning '4' for test case 'a = 1234'.

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


int main(){
    int a, length=1, rem, temp;
    printf("Enter number to be reversed: ");
    scanf("%d",&a);

    length = 4        /* hardcoding the length */

    /* reversing logic */
    for (int i= 1; i <= length; i++){
        rem = a%10;
        temp += rem*(pow(10,(length-i)));
        a /= 10;
    }

    printf("%d\n",temp);
    return 0;
}

This code executes perfectly for example for test case 'a = 1234' giving '4321'. Please provide insights why this problem may be occurring?

  • It is much easier (and efficient) to work with string input instead. Is that an option? – Lundin Aug 07 '23 at 09:10
  • @Lundin it may be, I haven't worked on them yet...just new to C. But for this particular approach only, what is the problem?? – AryanJotshi Aug 07 '23 at 09:12
  • 1
    You never initialize your `temp` variable. That ***may*** get a starting value of zero, sometimes, which would produce the correct answer, but it may equally well get a starting value of -1,000,000. Just add a `temp = 0;` line before your `for` loop. – Adrian Mole Aug 07 '23 at 09:13
  • Voting to close as a typo, or "resolved in a way that is not likely to be helpful for future visitors..." – Adrian Mole Aug 07 '23 at 09:14
  • Note that, if you enable **all** warnings, your compiler would very likely have told you that you are using an uninitialized variable. – Adrian Mole Aug 07 '23 at 09:16
  • Hint 1: you will save yourself and others a lot of time if you start using compiler [warnings](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings) (you should also enable optimisations). Hint 2: there is a much easier solution. You don't need to calculate the length of the number and you don't need to use `pow`. – n. m. could be an AI Aug 07 '23 at 09:19
  • It's best to avoid floating point math such as the `pow` function when dealing strictly with integer values. It can all be done in a single loop, gradually dividing the (positive) input by 10, multiplying the output by 10, and adding the remainder from the input division to the output. – Ian Abbott Aug 07 '23 at 09:19
  • For gcc, clang and icc/icx compilers, check out [What compiler options are recommended for beginners learning C?](https://software.codidact.com/posts/282565) – Lundin Aug 07 '23 at 09:21
  • @n.m.couldbeanAI :-) Hint 3: (for clarity, 'signed char temp' to use only a few bits...) You cannot reverse the value 125 because 521 will not fit into one byte... There's no protection in this code for such an overflow of a large-ish value. – Fe2O3 Aug 07 '23 at 09:28
  • What should the result of reversing `100` be? What length is it? If you `int len = sprintf(buf, "%d", n);` you get the length, and can easily output the digits in reverse order without omitting the trailing (now leading) zeros. – Weather Vane Aug 07 '23 at 09:33
  • @WeatherVane reversed `100` is one. – 0___________ Aug 07 '23 at 09:34
  • @0___________ I was not asking you. I was asking what *should* the result be. You don't know that, because OP did not say. – Weather Vane Aug 07 '23 at 09:41
  • @AdrianMole initializing temp worked, thanks!!! But why was it still working when I hardcoded the length variable and not when that length value was provided from the loop?? – AryanJotshi Aug 07 '23 at 09:48
  • @IanAbbott doesn't `(int) pow(10,2)` convert smth like `100.000000` into `100` ?? – AryanJotshi Aug 07 '23 at 09:51
  • @WeatherVane The expected output should be `1` only, which the corrected code shows... – AryanJotshi Aug 07 '23 at 09:56
  • It depends on the implementation of `pow`. On some implementations, the result of `pow(10,2)` could be slightly more or slightly less than 100. Applying the `(int)` typecast operation to a value slightly less than 100 would produce 99. – Ian Abbott Aug 07 '23 at 09:57
  • @IanAbbott some implementations means some different compilers, right? Or using it multiple times in same compiler may also result in different results? – AryanJotshi Aug 07 '23 at 09:59
  • The work-around is never to rely on exact results from floating point operations: so `(int)round(...)`. – Weather Vane Aug 07 '23 at 10:00
  • @AryanJotshi A particular implementation would produce the same result as long as the implementation remains unchanged by upgrades, etc. – Ian Abbott Aug 07 '23 at 10:03
  • @IanAbbott okay thanks! Can you give insights for the question I asked @AdrianMole?? – AryanJotshi Aug 07 '23 at 10:07
  • One of the nastiest things about undefined behaviour (like using an uninitialized variable) is that it can *appear* to work and then stop working for completely unrelated reasons (like adding extra code to your program). This appears to be one of those cases. – Adrian Mole Aug 07 '23 at 10:20
  • @AdrianMole Weird...thanks for clarifying though!!! – AryanJotshi Aug 07 '23 at 10:40

1 Answers1

2
  1. Do not use floating numbers functions like pow when you deal with integers
  2. Use larger integer type to store the result as the reversed number can overflow.
  3. Use functions
  4. You do not need to know the length of the integer in advance.
  5. You need to handle negative numbers as well.
long reverseInt(int x)
{
    long result = 0;
    int sign = x < 0 ? -1 : 1;

    while(x)
    {
        result *= 10;
        result += abs(x % 10);
        x /= 10;
    }
    return sign * result;
}


int main()
{
    printf("%ld\n", reverseInt(123456));
    printf("%ld\n", reverseInt(0));
    printf("%ld\n", reverseInt(INT_MAX));
    printf("%ld\n", reverseInt(INT_MIN));
}

https://godbolt.org/z/b7q9sGTT6

0___________
  • 60,014
  • 4
  • 34
  • 74