在无符号int和有符号int的值范围内,“-1”代表什么?

bis*_*uit 25 c

我正在学习C,并且对unsigned int和signed int的值范围中的“ -1”有一个愚蠢的问题。我似乎在任何地方都找不到它的解释。

以下段落说明了数据范围。但是,它没有解释“ -1”。“ -1”代表什么意思?是-1是因为它跳过0并且0没有值?

在32位整数中,无符号整数的范围为0到2 ^ 32 -1 = 0到4,294,967,295或大约40亿。签名版本从-2 ^ 31 -1到2 ^ 31,即–2,147,483,648到2,147,483,647,即大约-20亿到+20亿。范围是相同的,但是它在数字行上移动。

Yun*_*sch 47

考虑可以用2位获得的值:

00 : 0
01 : 1
10 : 2
11 : 3
Run Code Online (Sandbox Code Playgroud)

其中有4个,2等于2的幂。
但是最大值不是4,而是3。
最大值是2等于2的负1。即,您的表示形式

2 ^ 2-1
或2 2 -1

加一点,您将得到两倍的数字

100 : 4
101 : 5
110 : 6
111 : 7
Run Code Online (Sandbox Code Playgroud)

总数为8,但最高为7。

因此,“-1”是因为总将2 n
的第一个用于0,将第二个用于1,将第三用于2。
最后(2 n),第一个不用于2 n,已经用于2 n -1。


ike*_*ami 20

n位可以容纳2 n个不同的值。(第一位可以有两个值*第二位可以有两个值*第三位可以有两个值* ...)

例如,3位可以保存2 3 = 8个不同的值。

000
001
010
011
100
101
110
111
Run Code Online (Sandbox Code Playgroud)

如果每个位模式表示一个整数,则一个n位整数可以表示2 n个不同的整数。例如,

  • 它可以表示0到2 n -1之间的整数
    (包括(2 n -1)-(0)+ 1 = 2 n个不同的值)。

    例如,

    000   0
    001   1
    010   2
    011   3
    100   4
    101   5
    110   6
    111   7
    
    Run Code Online (Sandbox Code Playgroud)
  • 它可以表示包括-2 n-1到2 n-1 -1 的整数
    (因为(2 n-1 -1)-(-2 n-1)+1 = 2 n个不同的值)。

    例如,

    100  -4
    101  -3
    110  -2
    111  -1
    000   0
    001   1
    010   2
    011   3
    
    Run Code Online (Sandbox Code Playgroud)

您可以为这些值赋予任何含义,但是前面提到的范围是二进制补码机器分别理解的无符号整数和有符号整数的范围。[1]


  1. 在一个补码机上,有两种写入零的方式(0000 ... 0000 2和1000 ... 0000 2),因此范围仅为-2 n-1 -1至2 n-1 -1 。我认为所有现代机器都是二进制补码机器。


daS*_*ier 5

除了@Yunnosch对无符号数字的出色解释之外,几乎所有现代计算机都使用“二进制补码”表示有符号二进制整数。在二进制补码中,最高有效位用作“符号位”,而位是数字+1的绝对值的补码。因此,对于3位示例,无符号值的范围为0至7,范围为对于带符号的值是-4到3:

100 : -4
101 : -3
110 : -2
111 : -1
000 :  0
001 :  1
010 :  2
011 :  3
Run Code Online (Sandbox Code Playgroud)

请注意,对于带符号的数字,负数的范围比正数的范围大一个。这是因为,在数论中,0以二进制表示时,既不是正数也不0是负数。因为已清除的最高有效位0是正数域的一部分,所以剩下的正数少了一个。

  • 恐怕用“数字+ 1的绝对值的补码”这样的说法可能会误读为描述-1 =〜((1 + 1)->〜2->101。问题是缺少“()”散文,可以这样阅读。任何已经知道该机制的人都可以正确阅读您的文本,因此这没有错。但是那些需要解释的人可能会感到困惑。 (3认同)

dbu*_*ush 5

对于无符号整数类型,值 -1超出范围,无法用该类型的变量表示。如果您尝试将 -1 分配给一个unsigned int转换则会根据 C 标准的规则进行转换。

有符号值到无符号整数类型的转换在C 标准的 6.3.1.3p2 节中指定:

否则,如果新类型是无符号的,则通过重复加或减新类型可以表示的最大值1来转换该值,直到该值在新类型的范围内。60

...

60) 规则描述了数学值的算术,而不是给定类型表达式的值

假设您的示例中的unsigned int值范围为 0 到 4,294,967,295,则通过添加 -1 + 4,294,967,296 = 4,294,967,295 来转换值 -1。请注意,无论负数在给定系统上如何表示,都会发生这种转换。对于两个人的赞美、一个人的赞美或者符号和大小来说都是一样的。

请注意,这意味着转换后的值的表示不必与 -1 的表示相同。

以 4 位类型为例,将值 -1 转换为无符号类型会得到值 15。这些数字的表示如下:

                sign-and magnitude    ones' complement   two's complement
  -1   (signed)               1001                1110               1111
  15 (unsigned)               1111                1111               1111
Run Code Online (Sandbox Code Playgroud)

虽然在二进制补码的情况下,转换结果保持相同的表示形式,但在其他两种情况下它会发生变化。对于补码,-1 的表示与 14 相同,对于符号和数值,-1 的表示与 9 相同。

因此,其他答案所描述的关于补码的内容很可能是这些实现是如何实现的(即将 -1 的表示重新解释为无符号值),但是从 C 语言作为抽象机器的角度来看,我所描述的是唯一的执行此转换的正确方法。

  • 这是对如何在 C 中将 -1 转换为无符号值的问题的全面且具有启发性的报道。这就是我在阅读标题时所想到的问题。阅读问题正文和评论线程后,我不确定OP是否意味着“2^32-1”中的“-1”。 (2认同)