C++ 将 char 转换为 short
C++ casting char into short
请原谅我这个新手问题。我最近发现将 char 转换为 short 时有一件奇怪的事情。基本上,如果 char 溢出,当转换为 short 时,二进制数前面加上 11111111。如果 char 没有溢出,它将加上 00000000.
例如,
char a = 130;
short b = (short)a;
printf("%hhx\n", a);
printf("%hx\n", b);
打印
82
ff82
同时
char a = 125;
short b = (short)a;
printf("%hhx\n", a);
printf("%hx\n", b);
打印
7d
7d
因此,在进行转换时,在决定将其转换为什么二进制数之前是否检查变量类型和值(决定 b/w 在 0xFF 或 0x00 之前)?这背后有什么原因吗?似乎总是 (short)a & 0x00FF
是个好习惯?
char a = 130;
很有可能char
在你的系统上是8位的,我们可以根据输出结果猜测它是一个有符号类型。在这种情况下,char
的最大可表示值是 127。130 大于 127,因此它不可表示。在这种情况下,转换后的值将是与 130 模 128 一致的可表示值,即 -126。当您转换为两个字节 short
时,值保持不变 -126。 ff82 是 -126 表示为两个字节的二进制补码的方式。
It seems always doing (short)a & 0x00FF would be a good practice?
如果您这样做,那么 b
的值将与 a
的值 (-126) 不同 (130)。获得一个结果而不是另一个结果是一种“良好做法”吗?这取决于你需要什么样的结果。
位掩码只对无符号类型有意义。
将无法表示的值分配给有符号整数类型很少有意义。
继续阅读:2's complement负数如何以二进制编码。
在signed char
中,假设一个 8 位字符宽度和 2 的补码拱形,一个字符可以包含 -128 到 +127 之间的值。
当你说:
char a = 130;
超出范围。
130 作为 32 位二进制整数是:00000000 00000000 00000000 10000010
在十六进制中,它是:00 00 00 82
。这就是您的 82
值的来源。
当 int(130)
转换为 char 时,它基本上只是将最后一个字节的位全部砍掉:10000010
.
因此 char a = <binary:10000010>
在 2 的补码运算中是 -126
。
因此,当您分配 short b = a
时,您只是将 -126 分配给了一个短片。
在 2 的补码架构中,当负数被提升为更大的类型时,它会被“符号扩展”。也就是说,如果 signed char 的最高有效位是 1
,那么当它被转换为 short 时,额外的字节也会以 1
开头。也就是说,-126
作为 16 位二进制是:11111111 10000010
或 0xff82
尝试将 a
声明为 unsigned char
,您应该会得到不同的结果。
请原谅我这个新手问题。我最近发现将 char 转换为 short 时有一件奇怪的事情。基本上,如果 char 溢出,当转换为 short 时,二进制数前面加上 11111111。如果 char 没有溢出,它将加上 00000000.
例如,
char a = 130;
short b = (short)a;
printf("%hhx\n", a);
printf("%hx\n", b);
打印
82
ff82
同时
char a = 125;
short b = (short)a;
printf("%hhx\n", a);
printf("%hx\n", b);
打印
7d
7d
因此,在进行转换时,在决定将其转换为什么二进制数之前是否检查变量类型和值(决定 b/w 在 0xFF 或 0x00 之前)?这背后有什么原因吗?似乎总是 (short)a & 0x00FF
是个好习惯?
char a = 130;
很有可能char
在你的系统上是8位的,我们可以根据输出结果猜测它是一个有符号类型。在这种情况下,char
的最大可表示值是 127。130 大于 127,因此它不可表示。在这种情况下,转换后的值将是与 130 模 128 一致的可表示值,即 -126。当您转换为两个字节 short
时,值保持不变 -126。 ff82 是 -126 表示为两个字节的二进制补码的方式。
It seems always doing (short)a & 0x00FF would be a good practice?
如果您这样做,那么 b
的值将与 a
的值 (-126) 不同 (130)。获得一个结果而不是另一个结果是一种“良好做法”吗?这取决于你需要什么样的结果。
位掩码只对无符号类型有意义。
将无法表示的值分配给有符号整数类型很少有意义。
继续阅读:2's complement负数如何以二进制编码。
在signed char
中,假设一个 8 位字符宽度和 2 的补码拱形,一个字符可以包含 -128 到 +127 之间的值。
当你说:
char a = 130;
超出范围。
130 作为 32 位二进制整数是:00000000 00000000 00000000 10000010
在十六进制中,它是:00 00 00 82
。这就是您的 82
值的来源。
当 int(130)
转换为 char 时,它基本上只是将最后一个字节的位全部砍掉:10000010
.
因此 char a = <binary:10000010>
在 2 的补码运算中是 -126
。
因此,当您分配 short b = a
时,您只是将 -126 分配给了一个短片。
在 2 的补码架构中,当负数被提升为更大的类型时,它会被“符号扩展”。也就是说,如果 signed char 的最高有效位是 1
,那么当它被转换为 short 时,额外的字节也会以 1
开头。也就是说,-126
作为 16 位二进制是:11111111 10000010
或 0xff82
尝试将 a
声明为 unsigned char
,您应该会得到不同的结果。