2

I want to check if the reverse of an signed int value x lies inside INT_MAX and INT_MIN. For this, I have reversed x twice and checked if it is equal to the original x, if so then it lies inside INT_MAX and INT_MIN, else it does not.

But online compilers are giving a runtime error, but my g++ compiler is working fine and giving the correct output. Can anybody tell me the reason?

   int reverse(int x) {
        int tx=x,rx=0,ans;
        while(tx!=0){
            rx = rx+rx+rx+rx+rx+rx+rx+rx+rx+rx+tx%10;
            tx/=10;
        }
        
        ans = tx = rx;
        rx=0;
        
        while(tx!=0){
            rx = rx*10 + tx%10;
            tx/=10;
        }
        
        while(x%10==0&&x!=0)x/=10;
        //triming trailing zeros
        
        if(rx!=x){
            return 0;
        }else{
            return ans;
        }
      
        
    }

ERROR:

Line 6: Char 23: runtime error: signed integer overflow: 1929264870 + 964632435 cannot be represented in type 'int' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:15:23
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
UNREAL
  • 430
  • 5
  • 11
  • 15
    Signed overflow is undefined behavior in C++ ([Why is unsigned integer overflow defined behavior but signed integer overflow isn't?](https://stackoverflow.com/q/18195715/12122460)). The runtime error comes from a undefined behavior sanitizer, which tries to catch these undefined behaviors at runtime. – kotatsuyaki Jun 13 '22 at 01:14
  • 4
    Often, *as an extension to the C++ language*, particular compilers (sometimes in conjunction with a particular platform) will have an *implementation defined* behavior. That's great, unless... until the code needs to be ported to another platform or used with another compiler. – Eljay Jun 13 '22 at 01:16
  • 2
    don't you see `UndefinedBehaviorSanitizer` in the output? It's an [instrumentation tool](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) from some compilers and it simply means undefined behavior happened – phuclv Jun 13 '22 at 01:17
  • 1
    I get it now. didn't knew about sanitizer in c++. thanks. – UNREAL Jun 13 '22 at 01:25
  • Does this answer your question? [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) – Karl Knechtel Jun 13 '22 at 03:02

2 Answers2

0

I'm not sure what's wrong with your algorithm, but let me suggest an alternative that avoids doing math and the possibility of integer overflows.

If you want to find of if say, 2147483641 is a valid integer when reversed (e.g. 1463847412), you can do it entirely as string comparisons after converting the initial value to a string and reversing that string.

Basic algorithm for a non-negative value it this:

  • convert integer to string (let's call this string s)

  • convert INT_MAX to a string (let's call this string max_s)

  • reverse s. Handle leading zero's and negative chars appropriately. That is, 120 reversed is "21" and -456 reversed is "-654". The result of this conversion is a string called rev.

  • If rev.length() < s_max.length() Then rev is valid as an integer.

  • If rev.length() > s_max.length(), then rev is not valid as a integer.

  • If rev.size() == s_max.length(), then the reversed string is the same length as INT_MAX as a string. A lexical comparison will suffice to see if it's valid. That is isValid = (rev <= s_max) or isValid = strcmp(rev, s_max) < 1

The algorithm for a negative value is identical except replace INT_MAX with INT_MIN.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • I did it finally by checking ``if(ans<=INT_MAX -temp)`` each time while doing ``ans+=temp`` to avoid error and similar for -ve ans and this worked. Algorithm given in question is correct but leetcode compiler used an Instrument , that forced INT_MAX+1 to INT_MAX+1 and not to -2^31, which caused in runtime-error. – UNREAL Jun 13 '22 at 06:31
  • @UNREAL - I'm not sure I follow. Can you share the link to the leetcode challenge? – selbie Jun 13 '22 at 06:37
  • https://leetcode.com/problems/reverse-integer/ – UNREAL Jun 13 '22 at 06:38
  • @UNREAL - here's a link to my solution. I adapted it to the leetcode problem: http://cpp.sh/23rdg2 – selbie Jun 13 '22 at 06:49
0

According to the cppreference:

Overflows

... When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined: it may wrap around according to the rules of the representation (typically 2's complement), it may trap on some platforms or due to compiler options (e.g. -ftrapv in GCC and Clang), or may be completely optimized out by the compiler.

So the online compiler may comes with more strict checking, while your local GCC choosed to "wrap" on overflow.


Instead, if you want to wrap on overflow for sure, you may promote your operands to 64 bit width, perform the addition and then convert the result to 32 bit width again. According to cppreference this seems to be well defined after C++20.

Numeric conversions

Unlike the promotions, numeric conversions may change the values, with potential loss of precision.

Integral conversions

...

  • if the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is { implementation-defined (until C++20) } / { the unique value of the destination type equal to the source value modulo 2n where n is the number of bits used to represent the destination type. (since C++20) }

Example code on godbolt