c - 整数向下转换
c - integer downcast
关于 C 中的整数向下转换,例如
一个 int 值 000F'E000
向下转换为 short 或 unsigned short 将变为 E000
。
short
-> -8192
,
unsigned short
-> 57344
,
那么它只是削减了位吗?
upcast 呢?例如。 int -10
是 ffffff81
,转换为 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
向上转换为更大的整数更复杂:
- 对于unsigned到unsigned类型,它添加了足够的零最高有效字节;这始终保留值。
- 对于 signed 到 signed 类型,它对源类型进行符号扩展(即用位打包新字节等于源整数的符号位);这总是保留值,正数或负数
- 对于 unsigned 到 signed 类型,它有效地添加了足够的零最高有效字节;这总是保留值,因为在向上转换的性质中,目标中总是有更多的位,所以总是有 space 作为额外的符号 'bit'
- 对于 signed 到 unsigned 类型,它符号扩展,然后转换;这不能总是保留值,因为不能表示负值。
向下转换位,向上转换取决于"signedness"。无符号类型的向上转换为值添加零位,有符号类型的向上转换复制符号位。这样,表达式在向上转换前后具有相同的值。
为了将任何东西转换为无符号类型,值以模数 TYPE_MAX+1
进行调整,直到它在无符号类型的范围内。示例:-10
转换为范围为 0-65535 的 uint16_t
结果为 65536-10
或 65526
.
将任何东西转换为有符号类型:如果原始值在有符号类型的范围内,那就是结果。否则行为是 实现定义的 ,其中包括发出信号的可能性。编译器必须记录其在这种情况下的行为。
示例:-10
转换为 long long
导致 long long
的值为 -10
。位表示无关紧要,规则基于值。
由于在 printf
中使用了错误的格式说明符,您的测试程序包含许多未定义的行为。 (事实上 ,对于给定的参数,每个格式说明符都是错误的)。作为未定义的行为,输出是无意义的,所以不要尝试从这个程序中 "learn" 。相反,您可以研究标准中的规则或本网站上的其他答案,并阅读编译器的文档。
关于 C 中的整数向下转换,例如
一个 int 值 000F'E000
向下转换为 short 或 unsigned short 将变为 E000
。
short
-> -8192
,
unsigned short
-> 57344
,
那么它只是削减了位吗?
upcast 呢?例如。 int -10
是 ffffff81
,转换为 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
向上转换为更大的整数更复杂:
- 对于unsigned到unsigned类型,它添加了足够的零最高有效字节;这始终保留值。
- 对于 signed 到 signed 类型,它对源类型进行符号扩展(即用位打包新字节等于源整数的符号位);这总是保留值,正数或负数
- 对于 unsigned 到 signed 类型,它有效地添加了足够的零最高有效字节;这总是保留值,因为在向上转换的性质中,目标中总是有更多的位,所以总是有 space 作为额外的符号 'bit'
- 对于 signed 到 unsigned 类型,它符号扩展,然后转换;这不能总是保留值,因为不能表示负值。
向下转换位,向上转换取决于"signedness"。无符号类型的向上转换为值添加零位,有符号类型的向上转换复制符号位。这样,表达式在向上转换前后具有相同的值。
为了将任何东西转换为无符号类型,值以模数 TYPE_MAX+1
进行调整,直到它在无符号类型的范围内。示例:-10
转换为范围为 0-65535 的 uint16_t
结果为 65536-10
或 65526
.
将任何东西转换为有符号类型:如果原始值在有符号类型的范围内,那就是结果。否则行为是 实现定义的 ,其中包括发出信号的可能性。编译器必须记录其在这种情况下的行为。
示例:-10
转换为 long long
导致 long long
的值为 -10
。位表示无关紧要,规则基于值。
由于在 printf
中使用了错误的格式说明符,您的测试程序包含许多未定义的行为。 (事实上 ,对于给定的参数,每个格式说明符都是错误的)。作为未定义的行为,输出是无意义的,所以不要尝试从这个程序中 "learn" 。相反,您可以研究标准中的规则或本网站上的其他答案,并阅读编译器的文档。