一个字节的取值范围-128~127(原码、补码、反码)

在学习原码、反码、补码之前,需要先了解机器数和真值的概念。

机器数

  • 一个数在计算机中的二进制表示形式,叫做这个数的机器数。
  • 机器数是带符号的,在计算机用机器数的最高位存放符号,正数为0,负数为1。
  • 十进制中的数 +3 ,计算机字节为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。
  • 那么,这里的 00000011 和 10000011 就是机器数。

真值

  • 因为第一位是符号位,所以机器数的形式值就不等于真正的数值。
  • 例如有符号数 10000011,其最高位1代表负,其真正数值是 -3,而不是形式值131。
  • 将带符号位的机器数对应的真正数值称为机器数的真值。
  • 00000001的真值 = +0000001 = +1,10000001的真值 = –000 0001 = –1

原码

对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式。

原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。

00000001 => 1
01111111 => 127

10000001 => -1
11111111 => -127

反码

  • 正数的反码是其本身;
  • 负数的反码是在其原码的基础上,符号位不变,其余各个位取反。
+1 原码:00000001
+1 反码:00000001

+127 原码:01111111
+127 反码:01111111

-1 原码:10000001
-1 反码:11111110

-127 原码:11111111
-127 反码:10000000

可见如果一个反码表示的是负数,人脑无法直观的看出来它的数值。通常要将其转换成原码再计算。

补码

  • 正数的补码就是其本身;
  • 负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(也即在反码的基础上+1)
+1 原码:00000001
+1 反码:00000001
+1 补码:00000001

+127 原码:01111111
+127 反码:01111111
+127 补码:01111111

-1 原码:10000001
-1 反码:11111110
-1 补码:11111111

-127 原码:11111111
-127 反码:10000000
-127 补码:10000001

对于负数,补码表示方式也是人脑无法直观看出其数值的。通常也需要转换成原码再计算其数值。

为什么使用原码、补码、反码

+1的原码:00000001
+1的反码:00000001
+1的补码:00000001

-1的原码:10000001
-1的反码:11111110
-1的补码:11111111
  • 原码做加减

    原码做加法
    1+1=100000001 =>100000001 =>100000010 =>2
    
    原码做减法
    1+(-1)=000000001 =>110000001 =>-110000010 =>-2
    

    如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的。这也就是为何计算机内部不使用原码表示一个数。

  • 反码做加减

    反码做加法
    1+1=100000001 =>00000001 => 100000001 =>00000001 => 100000010 =>00000010 => 2
    
    反码做减法
    1+(-1)=000000001 =>00000001 => 111111110 =>10000001 => -111111111 =>10000000 => -0
    

    发现用反码计算减法,结果的真值部分是正确的。而唯一的问题其实就出现在"0"这个特殊的数值上,虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的,而且会有[0000 0000]原和[1000 0000]原两个编码表示0。

  • 补码做加减

    补码做加法
    1+1=100000001 =>00000001 =>00000001 => 100000001 =>00000001 =>00000001 => 100000010 =>00000010 =>00000010 => 2
    
    反码做减法
    1+(-1)=000000001 =>00000001 =>00000001 => 111111111 =>11111110 =>10000001 => -100000000 =>00000000 =>00000000 => 0
    

    这样0用 00000000 表示,而以前出现问题的-0则不存在了。而且可以用[1000 0000]表示-128:
    同时为了充分利用资源,就将原来本应该表示“-0”的补码规定为表明-128。这样就可以让有符号数多一个有用的数据点。
    这个值不能用普通的取反加1来计算。

而且1000 0000是-128刚好也可以满足基本的运算。
如下:

反码做减法
-1+(-127)=011111111 =>11111110 =>10000001 => -110000001 =>10000000 =>11111111 => -12710000000 => -128
<think>嗯,用户问的是关于MySQL中tinyint数据类型为什么负数取值范围比正数小,这需要从数据存储机制和二进制表示来解释。首先,我得回忆一下tinyint的基本信息。Tinyint在MySQL中占1个字节,也就是8位二进制数。如果是无符号的,范围是0到255,但用户提到的是有符号的情况,所以应该考虑符号位的影响。 有符号整数通常使用最高位作为符号位,0表示正数,1表示负数。剩下的7位用来表示数值。这样的话,正数的范围应该是0到127(包括0),而负数则是-1到-128。这里可能有个疑问,为什么负数的绝对值范围更大?比如,-128的绝对值是128,而正数最大是127。这是因为二进制补码的表示方法导致的。 补码表示法中,负数范围会比正数多一个。比如8位二进制补码可以表示的范围-128127。这是因为0占据了正数部分的一个位置,所以正数最大是01111111(127),而负数最小是10000000(-128)。所以当用户问为什么负数取值范围更小时,可能有点混淆,实际上负数的绝对值范围更大,但整体数值范围负数的下限到-128,而正数到127,所以总的范围-128127,但用户的问题可能是为什么正数的最大值比负数的最小值的绝对值小1。 需要解释补码的存储机制,包括原码反码补码的区别,以及为什么计算机使用补码来存储有符号整数。补码的优势在于统一了加减法的运算,不需要额外的电路来处理符号位。同时,补码中0的表示唯一,避免了原码中+0和-0的问题。 可能还需要提到,当使用tinyint有符号时,存储的最小值是-128,而最大值是127,所以正数的范围确实比负数的绝对值小1。这是因为补码的表示方式导致的,即负数的最小值对应的二进制是全1的情况,而正数最大是01111111,也就是127。 另外,用户可能对为什么负数范围不对称感到困惑,需要说明这是由于补码的编码方式决定的,尤其是在8位的情况下,这种不对称性是必然的。同时,可以对比其他整数类型,比如smallint或int,它们的负数范围同样比正数多一个,这也是同样的原因。 总结起来,回答需要包括以下几点: 1. tinyint的存储大小是1字节,8位二进制。 2. 有符号数的二进制表示使用补码。 3. 补码中符号位的解释和数值计算方式。 4. 为什么负数范围比正数多一个(比如-128127)。 5. 补码的优势,如简化运算、唯一表示0等。 需要确保引用正确的资料,比如引用中的[^5]提到tinyint适合年龄等小范围数值,但这里更关注的是存储机制,可能需要结合二进制补码的知识来解释。同时,用户可能对存储机制的具体细节感兴趣,比如补码如何转换,或者具体的例子说明。</think>### Tinyint数据类型负值范围小于正值的存储机制分析 在MySQL中,$TINYINT$ 是1字节(8位)的整数类型。其有符号取值范围为$-128 \sim 127$,而无符号为$0 \sim 255$。**负数范围绝对值比正数少1的根本原因是二进制补码表示法的规则**。 #### 1. 二进制补码的存储机制 有符号整数采用**补码(Two's complement)**表示,具体规则如下: - **最高位为符号位**:0表示正数,1表示负数 - **数值计算**:正数直接转换为十进制,负数需对补码取反后加1 例如: - 正数$127$的二进制:$01111111$ - 负数$-128$的二进制:$10000000$ 此时,正数最大值为: $$ 01111111_2 = 2^6 + 2^5 + \cdots + 2^0 = 127 $$ 而负数最小值的补码为: $$ 10000000_2 \rightarrow 取反加1后 = -128 $$ #### 2. 范围不对称的原因 补码的编码规则导致: - **正数范围**:$0 \sim 127$(共128个值) - **负数范围**:$-1 \sim -128$(共128个值) - **0的编码唯一性**:$00000000$仅表示$0$ 由于$0$占用了正数部分的一个编码位置,导致正数最大值比负数绝对值小1。这种设计使得补码能统一加减法运算逻辑,且避免原码中$+0$和$-0$的二义性问题。 #### 3. 补码优势对比 | 编码方式 | 运算复杂度 | 零表示 | 数值范围(8位) | |----------|------------|--------|---------------------| | 原码 | 高 | 两种 | $-127 \sim +127$ | | 反码 | 中 | 两种 | $-127 \sim +127$ | | 补码 | 低 | 一种 | $-128 \sim +127$ | 补码通过牺牲一个正数编码位置,换取了计算效率的提升和零的唯一性。 ```plaintext 示例存储过程: 1. 写入-128 → 二进制10000000 2. 写入127 → 二进制01111111 3. 读取时根据符号位判断正负 ``` #### 4. 总结 **Tinyint的负数范围绝对值更大是补码规则的自然结果**。这种机制既保证了硬件运算效率,又简化了数据存储逻辑。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值