c++ unix 32bit到Red Hat Linux,运行在x86_64芯片上(64位服务器)

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

本文关键字:芯片 服务器 64位 x86 32bit unix Red Hat 运行 Linux c++      更新时间:2023-10-16

我正在从事一个项目,该项目将c++应用程序从32位unix移植到运行在x86_64芯片(64位服务器)上的Red Hat Linux。我正面临与长数据类型相关的问题。我编写了一个示例程序来打印二进制长和无符号长值1。中间有一个额外的1:

ul = 00000000000000000000000000000000000100000000000000000000000000000001
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。这会导致我的应用程序出现运行时问题。请让我知道。我在运行在x86_64芯片(64位服务器)而不是unix上的Red Hat Linux中获得了额外的1个中间,这就是运行时问题的原因。有什么想法请告诉我

问题就在这里:

unsigned long mask = (1 << n);  

显然,在您的系统上,unsigned long有8个字节,而正常的int有4个字节。

这里有一个值为1的int(如果没有显式指定其他内容,则每个文字值都是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