我正在开发一个项目,将使用C ++的应用程序从32位unix移植到运行在x86_64芯片(64位服务器)上的Red Hat Linux。我面临与长数据类型相关的问题。我编写了一个示例程序来打印二进制long和unsigned long值为1.中间有一个额外的1:
ul = 00000000000000000000000000000001000000000000000000000000000000000001
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;
}
你们都可以看到我没有得到为什么有一个额外的1 IN MIDDLE。这导致我的应用程序中出现运行时问题。请告诉我。 我在x86_64芯片(64位服务器)上运行的Red Hat Linux中获得了额外的1中间而不是unix,这是运行时问题的原因。有任何想法请告诉我。
答案 0 :(得分:1)
问题在于:
unsigned long mask = (1 << n);
显然,unsigned long
有8个字节,而正常int
在您的系统上有4个字节。
这里有int
,其值为1(如果没有明确指定其他内容,则每个文字值为int
)。您正在对此4字节int
进行移位,然后然后将结果转换为8字节以将其保存在mask
中。在4字节中移位超过31位太多,但直到63位才这样做。
要解决此问题,您必须告诉编译器1
是8字节unsigned long
。
三个可能性:
unsigned long mask = (1UL << n);
//or
unsigned long mask = ((unsigned long)1 << n);
//or just
unsigned long mask = 1;
mask = mask << n;
另一个功能(对于签名类型)有同样的问题
对于第一个版本,只使用L
,而不使用U
。