c - 整数向下转换

c - integer downcast

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

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

那么它只是削减了位吗?

upcast 呢?例如。 int -10ffffff81,转换为 long long 的规则是什么?


@Update

关于向上转型,我根据答案做了一些测试,发现2的补码有以下规则:

    签:
        positive -> positive:添加 0 作为前缀位,
        negative -> negative: 添加 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;
}

沮丧

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

Upcasts

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

  • 对于unsignedunsigned类型,它添加了足够的零最高有效字节;这始终保留值。
  • 对于 signedsigned 类型,它对源类型进行符号扩展(即用位打包新字节等于源整数的符号位);这总是保留值,正数或负数
  • 对于 unsignedsigned 类型,它有效地添加了足够的零最高有效字节;这总是保留值,因为在向上转换的性质中,目标中总是有更多的位,所以总是有 space 作为额外的符号 'bit'
  • 对于 signedunsigned 类型,它符号扩展,然后转换;这不能总是保留值,因为不能表示负值。

向下转换位,向上转换取决于"signedness"。无符号类型的向上转换为值添加零位,有符号类型的向上转换复制符号位。这样,表达式在向上转换前后具有相同的值。

为了将任何东西转换为无符号类型,值以模数 TYPE_MAX+1 进行调整,直到它在无符号类型的范围内。示例:-10 转换为范围为 0-65535 的 uint16_t 结果为 65536-1065526.

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

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


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