为什么unsigned int x = -1和int y = ~0具有相同的二进制表示?

时间:2010-06-29 13:36:44

标签: c binary

在以下代码段中将会是:

  • 功能的结果
  • x的值
  • y的值
    {
         unsigned int x=-1;
         int y;
         y = ~0;
         if(x == y)
             printf("same");
         else
             printf("not same");
     }
a. same, MAXINT, -1
b. not same, MAXINT, -MAXINT
c. same , MAXUINT, -1
d. same, MAXUINT, MAXUINT
e. not same, MAXINT, MAXUINT

有人可以解释一下它是如何工作的,或者只是解释一下片段吗?

我知道它是关于两个补码等等。 MAXINT和-1的意义是什么? 这是因为unsigned int和int的事情 - 我是对的吗?

5 个答案:

答案 0 :(得分:12)

unsigned int x=-1;

1是一个整数文字,类型为int(因为它适合int)。应用于-的一元int不会导致进一步促销,因此-1int,其值为-1

当转换为unsigned int模2时,使用N ^算法,其中N是unsigned int中的值位数。 x的值为2 ^ N - 1,即UINT_MAX(什么是MAX_UNIT?)。

int y;
y = ~0;

再次0是类型int,在C中,int的所有允许表示必须具有int的所有值位,表示0为0.再次没有促销对于一元~发生,因此~0int,所有值位都是1.它的值是依赖于实现但它是负的(符号位将被设置)所以绝对不是UINT_MAXINT_MAX。该值存储在y未更改。

if(x == y)
    printf("same");
else
    printf("not same");

在此比较中,y将转换为unsigned int,以便与已x的{​​{1}}进行比较。由于unsigned int具有实现值,转换为y后的值仍然是实现定义的(尽管转换本身是模2 ^ N且已完全指定)。比较的结果仍然是实现定义。

总之:

  

实施定义,unsigned int,实施定义

在实践中补充:

  

不一样,UINT_MAX, - 0(又名0)

符号加幅度:

  

不一样,UINT_MAXUINT_MAX

两个补充:

  

相同,INT_MIN, - 1

答案 1 :(得分:8)

非常简单。 -1的二进制补码表示为0xFFFFFFFF。因此,这就是x包含的内容。

补码运算符(〜)翻转所有位。所以0的补码是32位数,所有位都设置为1或0xFFFFFFFF。

编辑:正如他所评论的那样。答案不是A.如果是,那么它会说0x7FFFFFFF和0xFFFFFFFF是相同的。他们不是。真正的答案是C(假设MAXUNIT是拼写错误;))。

答案 2 :(得分:8)

如果你运行这个程序,你会发现答案是错误而c是正确答案:

#include <stdio.h>
#include <limits.h>

int main() {
    unsigned int x=-1;
    int y;
    y = ~0;
    if(x == y)
        printf("same\n");
        if(x==INT_MAX) printf("INT_MAX\n");
        if(x==UINT_MAX) printf("UINT_MAX\n");
    else
        printf("not same");
    return 0;
}

答案 3 :(得分:2)

这是因为twos-complement

位的翻转导致匹配-1

的位模式

答案 4 :(得分:1)

因为在第一个unsigned int中,你输入-1,但是从unsigned int的角度看它是0xFFFFFFFF(这是负整数存储到计算机中的方式);在第二种情况下,按位不会完全不看“种类”并将“变换”0变为1而反之亦然,因此0的所有0都变为1(查看位),因此您获得0xFFFFFFFF。

接下来的问题是,为什么将无符号整数与有符号整数进行比较并不能区分它们? (数值上4294967295当然不等于-1,即使它们在计算机中的表示是相同的)。事实上它可以,但显然C并没有强制要求这样的区别,并且它是“自然的”,因为处理器不能自己做(我不确定这最后一句是总是 true,...但它适用于大多数处理器):要考虑到asm中的这种区别,您必须添加额外的代码。

从C的角度来看,你必须决定是将int转换为unsigned int,还是将int转换为unsigned int。但是当然,负数不能转换为无符号数,而另一方面,无符号数可能导致溢出(例如,对于4294967295,您需要一个64位寄存器(或33位寄存器!)才能拥有它仍然能够计算其负值)...

最自然的事情是避免奇怪的转换,并允许“cpu like”比较,在这种情况下导致0xFFFFFFFF(32位为-1)与0xFFFFFFFF(32位为~0)相比,这是相同的,更多在genereal中可以被认为是MAXUINT(可以保持的最大无符号整数),另一个是-1。 (看看你的机器limits.h包括检查它)