Reputation: 87
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
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