C++ 无符号字符未按预期工作
C++ unsigned characters not working as intended
我一直在处理无符号数,但出于某些奇怪的原因,它们在这段代码中不起作用。
这是我的功能
string compare (unsigned char H[4])
{
unsigned int sum = H[3] + H[2] * 0x100 + H[1] * 0x100 * 0x100 + H[0] * 0x100 * 0x100 * 0x100;
switch(sum)
{
case 0x414b4220: return "akb"; break;
case 0x89425446: return "png"; break;
case 0xefbbbf3c: return "plist"; break;
case 0x4c574600:
case 0x5df90000: return "lwf"; break;
case 0x4a4d5000:
case 0x424d4900:
case 0x434c5300:
case 0x43485000:
case 0x53544700:
case 0x4d415000: return "bin"; break;
default: return "";
}
}
函数是这样调用的:
unsigned char C[4];
fin2>>C[0]>>C[1]>>C[2]>>C[3];
string ext = compare(C);
我得到的 sum 值的输出始终是 0x89425446,但是值 return 始终是“”。那我哪里错了?
注意:有时我得到的输出是0x80000000
我已经弄清楚问题了,希望:
H[0] * 0x100 * 0x100 * 0x100
(让我们假设 32 位整数)
根据this answer, 0x100
is actually a signed constant. Furthermore, according to implicit integer promotion rules:
unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
因此,H[0]
将被转换为 signed int,因此整个表达式是有符号的,所以 H[0]
of 0x89
将导致尝试获取 (signed int) (0x89000000)
的值,或者换句话说,您将遇到整数溢出 undefined behaviour,在您的情况下,这会给您一个意想不到的负值。
正如我在评论中提到的,将四个无符号字节转换为无符号整数的规范方法是:
unsigned int sum = (unsigned int) H[3]
| ((unsigned int) H[2] << 8)
| ((unsigned int) H[1] << 16)
| ((unsigned int) H[0] << 24);
这明确地将 H[]
提升为 unsigned int
,并且使用 <<
移位可避免意外的符号转换问题。
PS:请不要对其他用户无礼 - 当我看到你的评论时,我差点删除了这个答案。
我一直在处理无符号数,但出于某些奇怪的原因,它们在这段代码中不起作用。
这是我的功能
string compare (unsigned char H[4])
{
unsigned int sum = H[3] + H[2] * 0x100 + H[1] * 0x100 * 0x100 + H[0] * 0x100 * 0x100 * 0x100;
switch(sum)
{
case 0x414b4220: return "akb"; break;
case 0x89425446: return "png"; break;
case 0xefbbbf3c: return "plist"; break;
case 0x4c574600:
case 0x5df90000: return "lwf"; break;
case 0x4a4d5000:
case 0x424d4900:
case 0x434c5300:
case 0x43485000:
case 0x53544700:
case 0x4d415000: return "bin"; break;
default: return "";
}
}
函数是这样调用的:
unsigned char C[4];
fin2>>C[0]>>C[1]>>C[2]>>C[3];
string ext = compare(C);
我得到的 sum 值的输出始终是 0x89425446,但是值 return 始终是“”。那我哪里错了?
注意:有时我得到的输出是0x80000000
我已经弄清楚问题了,希望:
H[0] * 0x100 * 0x100 * 0x100
(让我们假设 32 位整数)
根据this answer, 0x100
is actually a signed constant. Furthermore, according to implicit integer promotion rules:
unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
因此,H[0]
将被转换为 signed int,因此整个表达式是有符号的,所以 H[0]
of 0x89
将导致尝试获取 (signed int) (0x89000000)
的值,或者换句话说,您将遇到整数溢出 undefined behaviour,在您的情况下,这会给您一个意想不到的负值。
正如我在评论中提到的,将四个无符号字节转换为无符号整数的规范方法是:
unsigned int sum = (unsigned int) H[3]
| ((unsigned int) H[2] << 8)
| ((unsigned int) H[1] << 16)
| ((unsigned int) H[0] << 24);
这明确地将 H[]
提升为 unsigned int
,并且使用 <<
移位可避免意外的符号转换问题。
PS:请不要对其他用户无礼 - 当我看到你的评论时,我差点删除了这个答案。