c - 整数向下转换
Posted
技术标签:
【中文标题】c - 整数向下转换【英文标题】:c - integer downcast 【发布时间】:2015-03-09 11:09:54 【问题描述】:关于 C 中的整数向下转换,例如
int 值 000F'E000
向下转换为 short 或 unsigned short 将变为 E000
。 short
-> -8192
,unsigned short
-> 57344
,
那么它只是简单地削减位吗?
那么向上转换呢?例如。 int -10
是ffffff81
,转换为long long
的规则是什么?
@Update
关于向上转换,根据答案我做了一些测试,发现使用 2 的补码有以下规则:
签: 正 -> 正:添加 0 作为前缀位, 负 -> 负:添加 1 作为前缀位, 未签名: 添加 0 作为前缀位,代码:
// integer numbers, downcast & upcast,
#include <stdio.h>
void downcastTest()
int i = 127<<13;
printf("%X, %hX, %hi\n", i, i, i);
void upcastTest()
int i = 127;
int j = -127;
printf("%x, %llx\n", i, (long long)i);
printf("%x, %llx\n", j, (long long)j);
int main(int argc, char * argv[])
downcastTest();
upcastTest();
return 0;
【问题讨论】:
您希望通过“向上转换”E000
获得什么价值?
@barakmanos 感谢提示,已更正为cast
,关于向上转换我已经更新了问题。
相关(如果不重复):***.com/q/19262851/694576
What is the rule for C to cast between short and int?的可能重复
【参考方案1】:
向下转型
转换为较小的整数类型会丢弃目标类型中不存在的最高有效位(最左边,因为您会在纸上写完整的二进制整数)。
向上转型
向上转换为更大的整数更复杂:
对于 unsigned 到 unsigned 类型,它会添加足够的零个最高有效字节;这始终保留该值。 对于 signed 到 signed 类型,它对源类型进行符号扩展(即使用等于源符号位的位打包新字节整数);这始终保留正值或负值 对于 unsigned 到 signed 类型,它有效地添加了足够的最重要的零字节;这始终保留值,因为在向上转换的性质中,目标中总是有更多位,因此总是有空间用于额外的符号“位” 对于 signed 到 unsigned 类型,它进行符号扩展,然后进行强制转换;这不能始终保留该值,因为无法表示负值。【讨论】:
谢谢,我认为任何正确的程序都不应该从有符号值转换为无符号值。 我会避免使用术语left most
,因为有些机器是大端,有些是小端
@JamesWierzba 我已经澄清了,但老实说,在小端机器上,左/右与大端机器没有区别,因为字节顺序没有左/右含义。
这通常是不正确的,您可能描述了某些特定平台的行为
除了“对于无符号到无符号类型”或“对于无符号到有符号类型”之外,该标准不支持您的任何观点。该标准从不指定符号扩展。【参考方案2】:
向下转换削减位,向上转换取决于“签名”。无符号类型的向上转换将零位添加到值中,有符号类型的向上转换复制符号位。这样,表达式在向上转换之前和之后具有相同的值。
【讨论】:
【参考方案3】:为了将任何内容转换为无符号类型,该值会以 TYPE_MAX+1
为模进行调整,直到它处于无符号类型的范围内。示例:-10
转换为 uint16_t
,其范围为 0-65535,结果为 65536-10
或 65526
。
用于将任何内容转换为有符号类型:如果原始值在有符号类型的范围内,则为结果。否则,行为是实现定义的,其中包括发出信号的可能性。编译器必须记录它在这种情况下的行为。
示例:-10
转换为 long long
导致 long long
的值 -10
。位表示无关紧要,规则是基于值的。
由于在printf
中使用了错误的格式说明符,您的测试程序包含许多未定义的行为。 (事实上,对于给定的参数,每个格式说明符都是错误的)。作为未定义的行为,输出是没有意义的,所以不要尝试从这个程序中“学习”。相反,您可以研究标准中的规则或此站点上的其他答案,并阅读编译器的文档。
【讨论】:
以上是关于c - 整数向下转换的主要内容,如果未能解决你的问题,请参考以下文章