Vikas Rai
Vikas Rai

Reputation: 87

C++ unix 32bit to Red Hat Linux running on an x86_64 chip (64-bit server)

I am working on a project that is porting application in C++ from 32 bit unix to Red Hat Linux running on an x86_64 chip (64-bit server). I am facing issues related to long data types.I wrote a sample program to print a binary long and unsigned long value of 1. This has an extra 1 in middle:

ul = 0000000000000000000000000000000100000000000000000000000000000001
l = 0000000000000000000000000000000100000000000000000000000000000001

string binary(unsigned long i)   
{   
int n = sizeof(unsigned long);  
string s;  
n *= 8;  
--n;  
while (n >= 0)   
{  
unsigned long mask = (1 << n);   
s += (mask & i ? "1" : "0");   
--n;  
}   
return s;  
}   
string binary(long i)  
{  
int n = sizeof( long);   
string s;   
n *= 8;  
--n;  
while (n >= 0)  
{   
long mask = (1 << n);   
s += (mask & i ? "1" : "0");  
--n;   
}   
return s;  
}   
int main()  
{  
unsigned long ul = 1;  
long l = 1;    
cout << "sizeof ul = " << sizeof ul <<  ", ul = "  <<ul<<  endl;   
cout << "sizeof l = "  << sizeof l  << ", l = " << l << endl;    
cout << "ul = " << binary(ul) << endl;   
cout << "l = "  << binary(l) << endl;    
return 0;  
}      

As you all can see I am not getting why there is an extra 1 IN MIDDLE. This is causing run time issues in my application. Please let me know. I am getting extra 1 middle in Red Hat Linux running on an x86_64 chip (64-bit server) not in unix and that is the cause of run time issues. Any idea please let me know.

Upvotes: 1

Views: 109

Answers (1)

deviantfan
deviantfan

Reputation: 11434

The problem is here:

unsigned long mask = (1 << n);  

Apparently, a unsigned long has 8 byte and a normal int has 4 byte on your system.

Here you have a int with value 1 (every literal value is int if nothing else is explicitely specified). You´re doing the shifting on this 4 byte int, and then the result is converted to 8 byte to save it in mask. Shifting more than 31 bit is too much in 4 byte, yet you´re doing it until 63 bit.

To solve the problem, you have to tell the compiler that 1 is meant a 8 byte unsigned long.
Three possibilites:

unsigned long mask = (1UL << n);  
//or
unsigned long mask = ((unsigned long)1 << n);  
//or just
unsigned long mask = 1;  
mask = mask << n;  

The other function (for the signed type) has the same problem.
With the first variant, use just L there, without U.

Upvotes: 1

Related Questions