Problem with My Reverse Integer Program

I am new to cplusplus.com and C++ programming.

I created this simple program to reverse an integer.

For example, if user types 1234, then the output is supposed to be 4321
If user input is - 345, then the output is supposed to be -543

This program almost works. If I provide a 2-digit number, the output is correct. If I provide a 4-digit number, the output is correct. However, if I provide a 3-digit number, the output is 1 less than what it is supposed to be.

I attempted debugging, but I can't figure out why the program produces erroneous result for 3-digit number.

Here is the code that I used (It's just a throwaway code)

Any assistance will be appreciated.

Thank you all in advance!




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <cmath>

int main ()
{
    int num;
    int revNum;

    std::cout << "Enter the number: ";
    std::cin >> num;

	// Prevent accidental changes to the original member variable
	long long copyOfNum = num;

	int storeNumberOfDigits = 1;

	int storeRevNum = 0;

	bool isNegative = false;



	while ( copyOfNum / 10 != 0 )
	{
		storeNumberOfDigits ++;

		copyOfNum = copyOfNum / 10;
	}

	//std::cerr << storeNumberOfDigits << std::endl;

	// Reset copyOfNum variable
	copyOfNum = num;



	if ( copyOfNum < 0 )
	{
		isNegative = true;
		copyOfNum = std::abs ( copyOfNum );
	}

	for ( ; storeNumberOfDigits > 0; storeNumberOfDigits --)
	{
		int digit = copyOfNum % 10;

		//std::cerr << digit << std::endl;

        int exponent = storeNumberOfDigits - 1;

        //std::cerr << exponent << std::endl;

        //std::cerr << pow ( 10, 2 ) << std::endl;

        storeRevNum = storeRevNum + digit * pow ( 10, exponent );

        std::cerr << storeRevNum << std::endl;

		copyOfNum = copyOfNum / 10;
	}

	if ( isNegative )
		storeRevNum = - std::abs ( storeRevNum );


	revNum = storeRevNum;

	std::cout << "The reversed number is " << revNum << std::endl;
}
I tried your code and saw no problems

1
2
3
Enter the number: 357
The reversed number is 753
 


1
2
Enter the number: 34567
The reversed number is 76543


perhaps it was a particular number that caused the issue?

http://cpp.sh/6qtc
Last edited on
Could you show an example of the output you get? I tested this code just now on a Windows 10 64-bit computer compiled with mingw-w64 (64-bit) and it worked just fine. What compiler are you using?
I have the following:

Windows 7 Home Edition 64-Bit (Compiled and Tested on this OS)
CodeBlocks IDE
I am using mingw as well

Because I am away from my computer right now, I am unable to provide detailed information on compiler and IDE versions, but I will update this thread with this information as soon as possible.


When I tested it, it was not a particular number that caused the issue. It was any number that was 3-digit long, both negative and positive.

Here is an example of what program did when I last tested it.

1
2
Enter the number: 456
The reversed number is 653


The debugging code,
 
std::cerr << storeRevNum << std::endl;


would show 599 when it is actually supposed to be 600 for the example above

I will try again when I get home and update the thread with the result.

Thank you so much for the replies.

I would find it strange that the output of your program could ever be 600. Since the reversed value of 600 is 006, which would simply be read in as 6. Reversing it gives 6. But that's not a part of this problem, just a little mistake in your example. Sorry for that, just happened to notice it.

I assume you are using the default version of mingw that ships with CodeBlocks then? This would be another version than I am using, so it might still be something compiler dependent.

I've checked your code twice now. It might be that I'm overlooking something, but it seems to be just fine. I cannot find any reason why this should not work. Maybe you used code that was slightly different from the one you posted and the few changes might be causing the issue? I cannot think off anything else.
 
std::cerr << storeRevNum << std::endl;


First output is supposed to be 600 because the first number in 653 (Above Example) is 600

Basically, it goes like this

1
2
3
600
650
654

So, 456 -> 654 (Correct)

When I ran the program on my machine it was like this
1
2
3
599
649
653

456 -> 653 (Incorrect)

@Shadowwolf
I did not make any changes before posting my original code on this thread. But I am glad that it's not the "code" but possibly my compiler/IDE/machine. At least, I have the right code.

I plan to recompile when I get home.

It could possibly be a rounding error in pow. It operates on floats, so the result could not be precise. It could return 599.9 instead of 600. When converting back to int this would produce 599. This could be the cause.
I too looked at pow() put both parameters are integers so the result will be integer also (i know it wont be "int" but it will be an integer) ie; 10^1 10^2, 10^3 etc

I also find it difficult to accept that a compiler would give a different answer like this.

Paste you code into cpp.sh (like i did in my link) and post the url link here so we can see it too, dont use the code on this page, take it from codeblocks. Like shadowwolf, i suspect your code has changed without you realising. It happens to the best of us from time to time.
> It could possibly be a rounding error in pow. It operates on floats, so the result could not be precise.
> It could return 599.9 instead of 600. When converting back to int this would produce 599. This could be the cause.

Yes.


>> I too looked at pow() put both parameters are integers so the result will be integer also

No.
A set of overloads or a function template for all combinations of arguments of arithmetic type not covered by 1-3). If any argument has integral type, it is cast to double. If any argument is long double, then the return type Promoted is also long double, otherwise the return type is always double. http://en.cppreference.com/w/cpp/numeric/math/pow



1
2
3
4
5
6
// invariant: does not cause integer overflow, if exponent == 0 then base != 0
long long ipow( int base, unsigned int exponent )
{
    if( exponent == 0 ) return 1 ;
    else return ipow( base, exponent-1 ) * base ;
}


And then, line 55:
1
2
// storeRevNum = storeRevNum + digit * pow ( 10, exponent );
storeRevNum = storeRevNum + digit * ipow ( 10, exponent );


And for std::abs for integers, #include <cstdlib>
http://en.cppreference.com/w/cpp/numeric/math/abs
Last edited on
I apologize it took long for me to reply back.

1. I logged on to Linux system at my school and copied the codes and compiled it. It worked as intended on the school's system

2. I came back home and recompiled it > It still produced erroneous result for 3-Digit numbers and 3-Digit Numbers only

3. I again made sure that the codes that I posted is exactly same as the one I have. No changes were made. I included <cstdlib> library as JLBorges suggested. Same issue.

4. I decided to remove the current compiler and I downloaded Cgywin. I installed 4.8.2-2 gcc-g++ GNU Compiler Collection, tweaked compiler settings in CodeBlocks as necessary and recompiled the codes. NOW, it is working as intended!

So, it was actually the compiler, it seems. I've been using the default version of minGW with CodeBlocks. I do not know the exact version. As a matter of fact, it was the very first compiler that I installed when I just got into C++ programming.

Thank you all so much!
>>No.
Why? the integers passed in will be promoted to doubles or floats but will still be point zero. how will that cause rounding? (not being rude, its a genuine question :)
> how will that cause rounding?

Floating point numbers and computations are inexact. Precisely at what value the loss of precision becomes apparent depends on the run-time floating point environment, and the standard library implementation.

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <cmath>

int main()
{
    std::cout << std::fixed  ;
    
    for( int p = 20 ; p <= 40 ; ++p )
    {
        std::cout << "std::pow( 10, " << p << ") == " <<  std::pow( 10, p ) << '\n' ; 
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
std::pow( 10, 20) == 100000000000000000000.000000
std::pow( 10, 21) == 1000000000000000000000.000000
std::pow( 10, 22) == 10000000000000000000000.000000
std::pow( 10, 23) == 99999999999999991611392.000000
std::pow( 10, 24) == 999999999999999983222784.000000
std::pow( 10, 25) == 10000000000000000905969664.000000
std::pow( 10, 26) == 100000000000000004764729344.000000
std::pow( 10, 27) == 1000000000000000013287555072.000000
std::pow( 10, 28) == 9999999999999999583119736832.000000
std::pow( 10, 29) == 99999999999999991433150857216.000000
std::pow( 10, 30) == 1000000000000000019884624838656.000000
std::pow( 10, 31) == 9999999999999999635896294965248.000000
std::pow( 10, 32) == 100000000000000005366162204393472.000000
std::pow( 10, 33) == 999999999999999945575230987042816.000000
std::pow( 10, 34) == 9999999999999999455752309870428160.000000
std::pow( 10, 35) == 99999999999999996863366107917975552.000000
std::pow( 10, 36) == 1000000000000000042420637374017961984.000000
std::pow( 10, 37) == 9999999999999999538762658202121142272.000000
std::pow( 10, 38) == 99999999999999997748809823456034029568.000000
std::pow( 10, 39) == 999999999999999939709166371603178586112.000000
std::pow( 10, 40) == 10000000000000000303786028427003666890752.000000

http://coliru.stacked-crooked.com/a/b273213f979957c7

EDIT: depends on the run-time floating point environment, the standard library implementation, and in many implementations, the compiler options that were in use.
For instance, see: https://msdn.microsoft.com/en-us/library/e7s85ffb.aspx
Last edited on
I wish that reported button said who by :)

wow, i wasn't expecting rounding at that level! outrageous!
Topic archived. No new replies allowed.