在 C 中转换为较大类型时填充值
Padding values when converting to larger types in C
案例 1:
int8_t a = -10;
int32_t b;
b = (int32_t)a;
案例 2:
uint8_t a = 10;
uint32_t b;
b = (uint32_t)a;
在这两种情况下,b 是什么?有什么保证吗?类型转换时多出来的3个字节会补0吗?
说明:字节越多,越大。
整数类型之间的转换保证"correct"。也就是说,如果要转换的值(无论其类型如何)在转换为类型中是可表示的,则结果将是相同的值。
在第一种情况下,-10 可表示为 int32_t
,因此 b
最终将保留 -10 的 32 位表示。在 2 的补码机器(几乎所有现代计算机)上,顶部会有很多 1。在 x86 上,cbw
、cwd
、cwde
和 cdq
指令用于执行此操作。
在第二种情况下,10 可表示为 uint32_t
,因此 b
最终将保留 10 的 32 位表示。顶.
您可以将其视为 "sign-extension"——当扩展有符号整数时,额外的位是从源操作数的 MSB 复制的——但这只是实现细节。规则是,如果它可以在目标类型中表示,它就在目标类型中正确表示。
C/C++ 给你的一个额外保证是,当缩小 无符号类型时——从更大的无符号整数转换为更小的无符号整数—— - 结果将与砍掉高位相同,无论该值是否可以用较小的类型表示。对于带符号的整数,所有赌注都不成立(但在实践中,同样的事情总是会发生,有时这意味着正值变成负值)。
案例 1:
int8_t a = -10;
int32_t b;
b = (int32_t)a;
案例 2:
uint8_t a = 10;
uint32_t b;
b = (uint32_t)a;
在这两种情况下,b 是什么?有什么保证吗?类型转换时多出来的3个字节会补0吗?
说明:字节越多,越大。
整数类型之间的转换保证"correct"。也就是说,如果要转换的值(无论其类型如何)在转换为类型中是可表示的,则结果将是相同的值。
在第一种情况下,-10 可表示为 int32_t
,因此 b
最终将保留 -10 的 32 位表示。在 2 的补码机器(几乎所有现代计算机)上,顶部会有很多 1。在 x86 上,cbw
、cwd
、cwde
和 cdq
指令用于执行此操作。
在第二种情况下,10 可表示为 uint32_t
,因此 b
最终将保留 10 的 32 位表示。顶.
您可以将其视为 "sign-extension"——当扩展有符号整数时,额外的位是从源操作数的 MSB 复制的——但这只是实现细节。规则是,如果它可以在目标类型中表示,它就在目标类型中正确表示。
C/C++ 给你的一个额外保证是,当缩小 无符号类型时——从更大的无符号整数转换为更小的无符号整数—— - 结果将与砍掉高位相同,无论该值是否可以用较小的类型表示。对于带符号的整数,所有赌注都不成立(但在实践中,同样的事情总是会发生,有时这意味着正值变成负值)。