我是 C 的初学者。我最近了解了2's Complement
表示负数的其他方法以及为什么2's complement
是最合适的方法。
我想问的是,例如,
int a = -3;
unsigned int b = -3; //This is the interesting Part.
现在,对于int类型的转换
标准说:
6.3.1.3 有符号和无符号整数
当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则保持不变。
否则,如果新类型是无符号的,则在新类型可以表示的最大值的基础上重复加减一,直到该值在新类型的范围内。
第一段不能用,因为-3
不能用unsigned int
.
因此第 2 段开始发挥作用,我们需要知道 unsigned int 的最大值。它可以在limits.h中作为UINT_MAX找到。这种情况下的最大值是这样的计算:4294967295
-3 + UINT_MAX + 1 = -3 + 4294967295 + 1 = 4294967293
现在4294967293
二进制是11111111 11111111 11111111 11111101
和-3
2 的补码形式是11111111 11111111 11111111 11111101
,所以它们本质上是相同的位表示,无论我试图分配什么负整数给 unsigned int,它总是相同的。所以 unsigned 类型不是多余的。
现在我知道printf("%d" , b)
根据标准这是一种未定义的行为,但这不是一种合理且更直观的做事方式。如果将负数表示为,则表示将是相同的2's Complement
,这就是我们现在所拥有的,并且使用的其他方式很少见,并且很可能不会在未来的发展中出现。
因此,如果我们只能有一种类型说 int ,那么现在 if int x = -1
then%d
检查符号位,如果符号位是则打印负数,1
并且%u
始终按原样解释普通二进制数字(位)。由于使用 . 已经处理了加法和减法2's complement
。因此,这种做事方式不是更直观、更简单。