【入门】机器数和真值

本文详细介绍了计算机中的机器数概念,包括带符号的表示方式、真值的定义,以及原码、反码和补码的表示方法及其在计算中的应用,特别强调了补码如何解决0的符号问题和表示范围扩大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

机器数和真值

1、机器数

一个数在计算机中的二进制表示形式就是这个数的机器数。机器数是带符号的,在计算机用机器数的最高位存放符号,正数为0,负数为1。

比如,十进制中的数 +5 ,计算机字长为8位,转换成二进制就是0000 0101。如果是 -5,就是 1000 0101 。

那么,这里的 0000 0101 和 1000 0101 就是机器数。

2、机器数的真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。

例如上面的符号数 1000 0101,其最高位1代表负,其真正数值是 -5,而不是形式值131(1000 0011转换成十进制等于133)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值

比如:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = -000 0001 = -1

二. 机器数的三种表示形式:原码、反码、补码

1. 原码

原码就是加了一位符号位的二进制数,正数符号位为0,负数符号位为1,符号位为最高位。 个人理解就是将真值里面的"+"转换为0,"-"转换为1。

| 十进制 | 真值 | 原码 | | :---: | :---: | :---: | | +2 | +000 0010 | 0000 0010 | | -2 | -000 0010 | 1000 0010 |

由此可以得出8位的二进制数的大小范围为[1111 1111, 0111 1111],也就是[-127, 127]对应java中byte数据类型的大小范围

2. 反码

正数的反码就是其原码,负数的反码则是符号位不变,其他位取反(0变1,1变0)

| 十进制 | 原码 | 反码 | | :---: | :---: | :---: | | +2 | 0000 0010 | 0000 0010 | | -2 | 1000 0010 | 1111 1101 |

3. 补码

正数的补码就是其原码,负数的补码则是反码+1

| 十进制 | 原码 | 反码 | 补码 | | :---: | :---: | :---: | :---: | | +2 | 0000 0010 | 0000 0010 | 0000 0010 | | -2 | 1000 0010 | 1111 1101 | 1111 1110 |

4. 为何使用反码、补码

使用原码进行计算的时候,对于人而言能够很轻易的辨别出符号位,然后直接对其他位数值进行计算。然而对于计算机的设计而言辨别出符号位就是一项非常复杂的工程,所以设计的时候就考虑让符号位直接参与计算,这样设计计算机就十分简单了。 对于加法而言符号位对于计算并没有影响,对于减法而言则考虑通过加上负数来转换为加法的方式进行计算。 如果通过原码来直接进行减法计算:

3 - 2 
= 3 + (-2)
= 0000 0011(原) + 1000 0010(原)
= 1000 0101
= -5

结果显而易见,如果通过原码来直接让符号位参与运算的话是不正确的,所以为了解决减法的问题引入了反码的概念。如果通过反码来进行减法计算:

3 - 2
 = 3 + (-2)   
 = 0000 0011(原) + 1000 0010(原)
 = 0000 0011(反) + 1111 1101(反)
 = 1 0000 0000(反) -- 最高位产生进位,结果+1
 = 0000 0001(反)
 = 0000 0001(原)
 = 1

结果正确,从上面例子看来如果通过反码进行减法运算的话是没有问题的,那为什么又需要补码呢,我们一起来看下面这个特殊的例子:

2 - 2
= 2 + (-2)
= 0000 0010(原) + 1000 0010(原)
= 0000 0010(反) + 1111 1101(反)
= 1111 1111(反)
= 1000 0000(原)
= -0

  0 + 0
= 0000 0000(原) + 0000 0000(原)
= 0000 0000(反) + 0000 0000(反)
= 0000 0000(反)
= 0000 0000(原)
= 0

由于对于0这个数字而言,正负号没有任何意义,但是经过计算却有可能出现[0000 0000]和[1000 0000]这两种不同的原码表示同一个数字0,这显然是不合理的,所以此时就引入了补码的概念。 如果通过补码来进行上述例子的计算:

2 - 2
= 2 + (-2)
= 0000 0010(原) + 1000 0010(原)
= 0000 0010(反) + 1111 1101(反)
= 0000 0010(补) + 1111 1110(补)
= 1 0000 0000(补) -- 最高位产生进位,进位舍弃
= 0000 0000(补)
= 0000 0000(反)
= 0000 0000(原)
= 0

  0 + 0
= 0000 0000(原) + 0000 0000(原)
= 0000 0000(反) + 0000 0000(反)
= 0000 0000(补) + 0000 0000(补)
= 0000 0000(反)
= 0000 0000(原)
= 0

由上述例子可以看出,补码完美的解决了0的符号问题以及0有两个不同原码表示的问题。而且[10000 0000]也可以用来表示-128:

-1 - 127
= -1 + (-127)
= 1000 0001(原) + 1111 1111(原)
= 1111 1110(反) + 1000 0000(反)
= 1111 1111(补) + 1000 0001(补)
= 1 1000 0000(补) --最高位产生进位,进位舍弃
= 1000 0000(补)

-1 - 127的结果为-128,上面例子中-1和-127补码相加后得出的补码也是-128。但是这个1000 0000(补)实际上对应的是之前的-0,所以这个补码是没有反码和原码的。 综上可以看出使用补码的话不仅0的符号问题和多原码问题可以解决,还可以多表示一个最小数。因此对于1字节而言,原码和反码的范围是[-127, 127],而补码的范围是[-128, 127],也可以解释java中int的范围是[-2, 2-1]。

转载自:机器数、真值、原码、反码和补码 - 知乎 (zhihu.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值