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

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

int 值 000F'E000 向下转换为 short 或 unsigned short 将变为 E000
short -> -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;
}

【问题讨论】:

标签: c type-conversion


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

    【讨论】:

      猜你喜欢
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2021-11-08
      • 1970-01-01
      相关资源
      最近更新 更多