【发布时间】:2017-05-15 10:10:05
【问题描述】:
我是 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 所以它们本质上是相同的位表示,无论我试图分配什么负整数,它总是相同的无符号int.So 不是无符号类型多余的。
现在我知道printf("%d" , b) 根据标准是一种未定义的行为,但这不是一种合理且更直观的做事方式。如果否定表示为2's Complement,则表示将是相同的,这就是我们现在所拥有的,并且使用的其他方式很少见,并且很可能不会在未来的发展中。
所以如果我们只能有一种类型说 int ,现在如果 int x = -1 然后 %d 检查符号位并打印负数如果符号位是 1 和 %ualways 解释纯二进制数字(位)原样。由于使用了2's complement,所以已经处理了加法和减法。那么,这种做事方式不是更直观、更简单吗?
【问题讨论】:
-
该标准仅描述了 99.9% 的现代 CPU 在将无符号数解释为有符号数时所公开的行为。所以,是的,大多数机器都按照标准所说的那样做。但是有符号和无符号 不是多余的 因此。
-
@tofro 你能详细说明一下吗,我不明白你的意思。
-
例如为了进行比较,了解数字是否必须被解释为有符号或无符号是至关重要的。
标签: c programming-languages twos-complement unsigned-integer language-concepts