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

Anu*_*bha 25 math bit-manipulation computer-architecture twos-complement

我读了 为什么Java中的字节范围是-128到127? 它说

128是10000000.倒置,它是01111111,再加一个得到10000000

所以它总结-128是10000000

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

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

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

Oli*_*rth 39

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

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

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

01111111 = +127
01111110 = +126
01111101 = +125
...
00000001 = +1
00000000 =  0
11111111 = -1
...
10000010 = -126
10000001 = -127
10000000 = -128
Run Code Online (Sandbox Code Playgroud)

所以代表-128 10000000或110000000?

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

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

人为地限制范围到-127不会达到很多; 你将不允许一个完全有效的值,并且通常使代码更复杂(你还能用bit模式做什么10000000?).

  • 当我开始写我的答案时,你的回答是一个单行.现在我看到它大部分已经过时了.你总是这样做吗?我的意思是回答一个班轮来抓住第一响应者的位置,然后逐渐改善它?看看你的REP,我猜你擅长这种技巧.+1 (3认同)

Aft*_*nix 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
Run Code Online (Sandbox Code Playgroud)

对于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
Run Code Online (Sandbox Code Playgroud)

另一方面,2的补码算法可以很好地与计算机内部的"固定"宽度计算存储(寄存器,存储器等)配合使用.

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


Fre*_*Foo 6

两个补码的替代方案是

  • 一个人的补充,由于其"负零"而出现问题
  • 符号/幅度,也有负零
  • 不分配含义10000000,在这种情况下,许多接受有符号8位整数的函数必须检查该无效值,浪费时间.(除非您的代码在假设的硬件上运行,将此位模式视为整数NaN.)

更简单地为该位模式赋予含义,并且二进制补码表示中的自然含义是-128.

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

if (highest_bit_zero(x))
    return false;
else if (x == 0b10000000)
    ERROR
else
    return true;
Run Code Online (Sandbox Code Playgroud)

你决定如何处理错误:)