1

I am writing a very simple test program to reverse the digits of an input number and raise it to the reverse. I am using unsigned long long in all operations in order to print all the digits in the result output. The following is the header file of the code:

#include <iostream>
#include <cstdlib>
#include <cmath>

class userinput{

        public:
                userinput(unsigned long long);
                ~userinput();
                unsigned long long reverse ();
                unsigned long long raise_to_reverse ();

        private:
                userinput();
                userinput(const userinput&);
                void operator=(const userinput&);

        private:
                unsigned long long value;
                unsigned int numDigits;
                unsigned long long revValue;
                unsigned long long result;

        private:
                void calc_numDigits();
                unsigned long long iPow ();


};

The following is the .cpp file, with all the function definitions:

#include "program.h"


userinput::userinput(unsigned long long value){

        this->value = value;
        this->revValue = 1ULL;
        this->result = 1ULL;
        calc_numDigits();
}


userinput::~userinput(){

}


unsigned long long userinput::reverse (){ 

        if(1 < this->numDigits){
                unsigned long long number = this->value;


                for( ; number!= 0 ; ){

                        this->revValue = this->revValue * 10; 
                        this->revValue = this->revValue + number%10;
                        number = number/10;
                }
        }
        else{

                this->revValue = this->value;
        }

        return this->revValue;
}


void userinput::calc_numDigits(){

        this->numDigits = (unsigned int) std::log10 (this->value) + 1 ; 
}



unsigned long long userinput::iPow(){

        while(this->revValue)
    if (this->revValue & 1ULL)
                {
                        this->result *= this->value;
                }
                this->revValue >>= 1;
                this->value *= this->value;
        }
        return this->result;
}



unsigned long long userinput::raise_to_reverse(){

        return iPow();
}
`                                

The following is the code in main.cpp:

   #include "program.h"


int main (){ 

        unsigned long long input;
        unsigned long long maxValue = 99999;

START:
        std::cout << "Enter a number between 0 and 99999 (exlusive):" << std::endl;
        std::cin >> input;

        if(input <= 0 || input >= maxValue){

                std::cerr << "Inadmissible value entered. Please try again." << std::endl;
                goto START;
        }   

        userinput number(input);

        std::cout << "Raising " << input << " to " << number.reverse() << " gives " << number.raise_to_reverse() << std::endl;

        return 0;
}

Now the problem I am facing is that, when I construct an object with the input value from the command-line, the value is copied without any issues to the member variable "value" of the userinput class object in the constructor. Here is the gdb output for the same:

    Enter a number between 0 and 99999 (exlusive):
1234

Breakpoint 1, userinput::userinput (this=0x7fffffffde00, value=1234) at program.cpp:6
6       this->value = value;
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64
(gdb) n
7       this->revValue = 1ULL;
(gdb) p this->value
$1 = 1234
(gdb) n
8       this->result = 1ULL;
(gdb) n
9       calc_numDigits();
(gdb) p this->value
$2 = 1234
(gdb) n

But when the function userinput::reverse() is called from main() as part of the next step, the previously stored quantity in the variable "value" is overwritten with another quantity for no apparent reason in the code. Here is the gdb output:

 Enter a number between 0 and 99999 (exlusive):
1234

Breakpoint 1, userinput::reverse (this=0x7fffffffde00) at program.cpp:20
20      if(1 < this->numDigits){
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64
(gdb) p this->value
$1 = 1522756
(gdb) 

As is seen in the output, the original value of 1234 has been overwritten by 1522756 for no apparent code. Can anyone point out what is going wrong here? Has it something to do with the way I am using unsigned long long?

Any suggestions would be deeply appreciated.

thanks Vinod

  • 1
    The code you posted can't compile (mismatched `}`). Please make sure what you post is actually what you compiled, and also make sure what you're seeing in your debugger isn't just an optimization artifact (i.e. compile with debug and disable optimizations). – Mat Aug 30 '15 at 10:40

1 Answers1

2

What's going on

1522756 is 1234*1234, which is set in

this->value *= this->value;

Why

You're missing that:

std::cout << a << b;

is equivalent to something like:

operator<<(operator<<(std::cout, a), b);

And as order of argument evaluation is unspecified by the standard, you actually call raise_to_reverse() before reverse() (this is specific to your compiler and its settings, don't rely on it).

Fix

Break your output statement into two to guarantee correct order of evaluation:

std::cout << "Raising " << input << " to " << number.reverse();
std::cout << " gives " << number.raise_to_reverse() << std::endl;
xaizek
  • 5,098
  • 1
  • 34
  • 60