c - 整数向下转换

Posted

技术标签:

【中文标题】c - 整数向下转换【英文标题】:c - integer downcast 【发布时间】:2015-03-09 11:09:54 【问题描述】:

关于 C 中的整数向下转换,例如

int 值 000F'E000 向下转换为 short 或 unsigned short 将变为 E000short -> -8192,unsigned short -> 57344,

那么它只是简单地削减位吗?

那么向上转换呢?例如。 int -10ffffff81,转换为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】:

向下转型

转换为较小的整数类型会丢弃目标类型中不存在的最高有效位(最左边,因为您会在纸上写完整的二进制整数)。

向上转型

向上转换为更大的整数更复杂:

对于 unsignedunsigned 类型,它会添加足够的零个最高有效字节;这始终保留该值。 对于 signedsigned 类型,它对源类型进行符号扩展(即使用等于源符号位的位打包新字节整数);这始终保留正值或负值 对于 unsignedsigned 类型,它有效地添加了足够的最重要的零字节;这始终保留值,因为在向上转换的性质中,目标中总是有更多位,因此总是有空间用于额外的符号“位” 对于 signedunsigned 类型,它进行符号扩展,然后进行强制转换;这不能始终保留该值,因为无法表示负值。

【讨论】:

谢谢,我认为任何正确的程序都不应该从有符号值转换为无符号值。 我会避免使用术语left most,因为有些机器是大端,有些是小端 @JamesWierzba 我已经澄清了,但老实说,在小端机器上,左/右与大端机器没有区别,因为字节顺序没有左/右含义。 这通常是不正确的,您可能描述了某些特定平台的行为 除了“对于无符号到无符号类型”或“对于无符号到有符号类型”之外,该标准不支持您的任何观点。该标准从不指定符号扩展。【参考方案2】:

向下转换削减位,向上转换取决于“签名”。无符号类型的向上转换将零位添加到值中,有符号类型的向上转换复制符号位。这样,表达式在向上转换之前和之后具有相同的值。

【讨论】:

【参考方案3】:

为了将任何内容转换为无符号类型,该值会以 TYPE_MAX+1 为模进行调整,直到它处于无符号类型的范围内。示例:-10 转换为 uint16_t,其范围为 0-65535,结果为 65536-1065526

用于将任何内容转换为有符号类型:如果原始值在有符号类型的范围内,则为结果。否则,行为是实现定义的,其中包括发出信号的可能性。编译器必须记录它在这种情况下的行为。

示例:-10 转换为 long long 导致 long long 的值 -10。位表示无关紧要,规则是基于值的。


由于在printf 中使用了错误的格式说明符,您的测试程序包含许多未定义的行为。 (事实上​​,对于给定的参数,每个格式说明符都是错误的)。作为未定义的行为,输出是没有意义的,所以不要尝试从这个程序中“学习”。相反,您可以研究标准中的规则或此站点上的其他答案,并阅读编译器的文档。

【讨论】:

以上是关于c - 整数向下转换的主要内容,如果未能解决你的问题,请参考以下文章

在C中除以整数将值向下舍入/结果为零

在 Swift 中安全地从 Int 向下转换为 Int8

c_cpp 在C ++中进行强制转换和向下转换

在 Swift 中“向下转换”C 结构

c_cpp 向下或向上转换的C ++类示例

C ++:如何遍历类类型列表以进行类型标识验证和向下转换?