【问题标题】:Why do unsigned int x = -1 and int y = ~0 have the same binary representation?为什么 unsigned int x = -1 和 int y = ~0 具有相同的二进制表示?
【发布时间】:2011-03-09 15:25:39
【问题描述】:

在下面的代码段中会是什么:

  • 函数的结果
  • x的值
  • y 的值
{ 无符号整数 x=-1; 整数y; y = ~0; 如果(x == y) printf("相同"); 别的 printf("不一样"); } 一种。相同,MAXINT,-1 湾。不一样,MAXINT,-MAXINT C。相同, MAXUINT, -1 d。相同,MAXUINT,MAXUINT e.不一样,MAXINT,MAXUINT

有人可以解释一下它是如何工作的吗?或者可以解释一下 sn-p 吗?

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

【问题讨论】:

  • 答案不是 A。
  • 不应该是MAXUINT,而不是MAXUNIT吗?
  • 如果同样的程序按原样运行,在 32 位系统上的答案难道不是 (A) 吗?

标签: c binary


【解决方案1】:

unsigned int x=-1;

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

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

int y;
y = ~0;

同样0int 类型,在C 中int 的所有允许表示必须具有将0 表示为0 的int 的所有值位。同样,对于一元~ 不会进行提升所以@ 987654342@ 是一个int,所有值位都是1。它的值取决于实现,但它是负数(将设置符号位),所以绝对不是UINT_MAXINT_MAX。此值原封不动地存储在y 中。

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

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

总之:

实现定义,UINT_MAX,实现定义

在补码的实践中:

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

符号加幅度:

不一样,UINT_MAXINT_MIN

补码:

相同,UINT_MAX,-1

【讨论】:

  • 我是否理解正确,它实际上取决于实现并且所提出的问题有些缺陷?我认为标准的相关部分是section 6.2.6.2 §2(pdf)
  • +1 我没有意识到有符号整数的实现是not在 C 标准中定义的。它可以是二的补码一个的补码符号和幅度。这是需要考虑的事情(尽管它实际上总是二进制补码)。
【解决方案2】:

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

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

编辑:正如他在 cmets 中指出的那样。答案不是 A。如果是,那么它会说 0x7FFFFFFF 和 0xFFFFFFFF 是相同的。他们不是。真正的答案是 C(假设 MAXUNIT 是一个错字;))。

【讨论】:

  • 是的,我知道它关于两个恭维可能是我的问题是错误的,为什么在 ans 选项中他们给出了 MAXINT n -1 等东西,我不明白它们明显相同的重要性。 ..bt 他们有三个选项说相同的 n 其他的事情与选项...请给我打电话
  • 这不是说正确答案应该是 c(假设 UNIT 应该是 UINT)吗?反正我就是这么说的。
  • 好吧,因为 -1 是无符号的,所以它给了 MAXINT n,因为 y 是 int,它给了我们 -1??
  • 我认为编译器会抱怨将 -1 分配给无符号整数,但它确实可以编译 - 有趣。
  • @Darel 实际上... C 是 C!您可以比任何其他语言更容易映射到 asm(除了 asm!)...汇编程序不能抱怨,比如“mov eax,-1”或“mov eax,FFFFFFFFh”... cpu 无法区分... :D
【解决方案3】:

如果你运行这个程序,你会看到答案 a 是错误,而 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;
}

【讨论】:

  • @shraddha:不幸的是,C 语言留下了很多未指定的内容,因此在一个特定的实现上运行程序(即使是已知 100% 符合的)并不能告诉你该语言指定了什么。这只是一个“最终”答案。
【解决方案4】:

因为twos-complement

位的翻转导致匹配 -1 的位模式

【讨论】:

  • 是的,我知道它关于两个恭维可能是我的问题是错误的,为什么在 ans 选项中他们给出了 MAXINT n -1 等东西,我不明白它们明显相同的重要性。 ..bt 他们有三个选项说相同的 n 其他事情与选项.. 请告诉我..
  • 我不知道 MAXUNIT 的存在......至于 MAXINT,A) 说 MAXINT 是 -1 (int),而且你已经知道为什么,知道 2s 技术。我认为这两个值(MAXINT,-1;MAXUNIT,-MAXUNIT)是“有效”比较的值。所以,向后看,即使忽略 MAXUNIT 是什么,答案肯定是第一个,因为 MAXINT 和 -1 是相同的,而且你从程序中得到的......(有点重言式?)
  • 我之前的评论是错误的:MAXUINT 等于-1。 (是 MAXUNIT 确实是 MAXUINT)
【解决方案5】:

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

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

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

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

【讨论】:

  • 重要评论:正如其他地方所说,我同意 sepp2k,如果 MAXUNIT 确实是 MAXUINT,因为 MAXUINT 是 4294967295(在 32 位机器上)并且 MAXINT 确实是 2147483647,在 32 位机器上...... ,所以 C 是正确的,而不是 A
  • 对评论的元评论:我在 sepp2k 发布他的答案之前发表了这个评论和其他评论:我指的是他/她的 cmets。
猜你喜欢
  • 2014-11-09
  • 1970-01-01
  • 2021-08-07
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多