为什么有符号字节的范围是-128到127(2的补码)而不是-127到127?

时间:2012-07-11 13:31:23

标签: math bit-manipulation computer-architecture twos-complement

我看了 Why is the range of bytes -128 to 127 in Java? 它说

  

128是10000000.倒置,它是01111111,并且添加一个   再次10000000

所以它总结-128是10000000

所以+128不能用8位的2的补码表示,但这意味着我们可以用9位表示它,所以128是010000000,所以取其2的补码-128是110000000,

表示-128 10000000或110000000? 表示位是否依赖?

为什么不简单地将较低的范围-127改为8位而不是将-128写为10000000?

5 个答案:

答案 0 :(得分:39)

  

为什么无符号字节的范围是-128到127?

不是。无符号字节(假设为8位)为0到255。

使用2的补码的带符号字节的范围是-128到127,直接来自2's complement的定义:

01111111 = +127
01111110 = +126
01111101 = +125
...
00000001 = +1
00000000 =  0
11111111 = -1
...
10000010 = -126
10000001 = -127
10000000 = -128
  

表示-128 10000000或110000000?

在8位中,它是10000000,在假设的9位表示中,它是110000000

  

为什么不简单地将较低范围-127设为8位?

人为地将范围限制在-127不会达到很高的水平;您将不再使用完全有效的值,并且通常会使代码更复杂(您还可以使用位模式10000000做什么?)。

答案 1 :(得分:17)

  

表示-128 10000000或110000000?表示位是否依赖?

是的,2的补码表示是依赖于位的

  

为什么不简单地将较低的范围-127转换为8位而不是将-128写为10000000

2 ^ 8 = 256.因此,无论您使用何种表示方案,它都应该能够表示256个不同的值。

你可以绘制一个圆来理解2的补体系统是多么好。

首先看一下这个表:

Bits    Unsigned 2's complement
00000000    0   0
00000001    1   1
00000010    2   2
01111110    126     126
01111111    127     127
10000000    128     −128
10000001    129     −127
10000010    130     −126
11111110    254     −2
11111111    255     −1

对于2的补充系统,您可以绘制圆圈以理解该系统。

这是4位版本。您可以轻松自行开发8位版本。这个圆圈代表了这个2的补充系统实际上是什么。它是一个循环系统。这意味着它的表示取决于你给它的“跨度”。这就是为什么8位版本的负数将与16位版本的相同负数不同。您可以比较在圆圈中给出的4位版本中的相同负数与表中给出的8位版本。

                      0000  0
                 1111  -1     0001  1


        1110  -2                       0010  2




  1101  -3                                   0011  3



1100  -4                                       0100  4



  1011  -5                                   0101  5




        1010  -6                       0110  6


                 1001  -7     0111  7
                          1000  -8

另一方面,2的补码算法适用于计算机内部的“固定”宽度计算存储(寄存器,存储器等)。

在第一代计算机中,存在提供原生十进制算术的趋势。但是这很快被放弃了,有利于“补充”或“循环”方案,因为从计算机的角度来看,十进制算术是奇怪的。我们发现它很自然,因为“我们有10个手指”。这些手指是我们祖先最早的计算工具。这就是为什么我们发现十进制系统如此自然。它内置于我们的基因中。

答案 2 :(得分:6)

两个补码的替代方案是

  • one's complement,由于其“负零”而出现问题
  • sign/magnitude,也有负零
  • 没有为10000000分配含义,在这种情况下,许多接受有符号8位整数的函数必须检查该无效值,浪费时间。 (除非您的代码在假设的硬件上运行,将该位模式视为整数NaN。)

更容易为该位模式赋予含义,并且二进制补码表示中的自然含义是-128。

例如,在二进制补码中,检查是否为负,以检查其最高位是否已设置。在10000000无效的变体中,它是(伪代码)

if (highest_bit_zero(x))
    return false;
else if (x == 0b10000000)
    ERROR
else
    return true;

您决定如何处理错误:)

答案 3 :(得分:3)

  

表示-128 10000000或110000000?表示位是否依赖?

在一个9位的世界中,它将是110000000.在一个16位的世界中,它将是1111111110000000.至少,只要我们说的是两个补码。

  

为什么不简单地将较低范围-127设为8位而不是将-128设为10000000?

正如larsmans指出的那样,你最终会得到一个“无效”的值,你经常需要检查它。已经选择了两个补码,因为ALU很容易处理。就像字节宽度被选择为2的幂(这也不是总是如此)。在硬件级别,二进制补码与无符号相同,因此不需要特殊指令或额外硬件(与一个补码不同)。

对于它们的方式,具有最高位设置的所有值都是负的,具有最高位未设置的所有值都是非负的(正或零)。容易,不是吗?负范围比正范围大一个只是试图保持两个补码简单的人为因素。

答案 4 :(得分:2)

您不能拥有从enter image description hereenter image description here的范围的原因。

看起来enter image description hereenter image description here由相同的模式表示。这个不好。非零整数及其负数不能都由相同的模式表示。所以enter image description here不能用8位表示。可以用8位表示的最大正整数是enter image description here

1000 0000代表什么号码?将enter image description here的表示添加到其中:

enter image description here

一个不错的选择?是enter image description here。因此,1000 0000代表enter image description here。八位可用于表示数字enter image description here ... 0 ... enter image description here

enter image description here

例如,可以使用二进制补码以八位表示的整数范围是:

Example

请注意,可以表示一个负整数,而不是正整数。

来源: - http://programmedlessons.org/AssemblyTutorial/Chapter-08/ass08_20.html