机器数和真值
机器数
机器数是将符号 数字化 的数,是数字在计算机中的二进制表示形式。
机器数有2个特点:
一是符号数字化
机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.
比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是 00000011
。
如果是 -3 ,就是 10000011
。
那么,这里的 00000011
和 10000011
就是机器数。
二是其数的大小受机器字长的限制
机器内部设备一次能表示的二进制位数叫机器的字长,一台机器的字长是固定的。字长8位叫一个字节(Byte),机器字长一般都是字节的整数倍,如字长8位、16位、32位、64位。
真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。
例如上面的有符号数 10000011
,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011
转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值
。
例:0000 0001
的真值 = +000 0001
= +1
1000 0001
的真值 = –000 0001
= –1
原码, 反码, 补码
- C语言中,所有的整型数据实际存储的都是补码。
- 正数的原码、反码、补码是一致的;
- 负数的补码是反码加1,反码是对原码按位取反,只是最高位(符号位)不变;
- 计算机数字运算均是基于补码的。
原码
将数的真值形式中 +
号用 0
表示,-
号用 1
表示时,叫做数的原码形式,简称原码
。
最高位为符号位,0代表正数,1代表负数。
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
1 | [+1] = 0000 0001 (原码) |
反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位(最高位)不变,其余各个位取反。
1 | [+1] = [00000001]原 = [00000001]反 |
补码
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
1 | [+1] = [00000001]原 = [00000001]反 = [00000001]补 |
原码求补码
正数
正整数的补码是其二进制表示,与原码相同。
负数
求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1。
例:求-5的补码。
-5对应带符号位负数5(10000101
)→除符号位外所有位取反(11111010
)→加 00000001
为 (11111011
),所以-5的补码是 11111011
。
数0的补码表示是唯一的
[+0]补=[+0]反=[+0]原=00000000
[-0]补=11111111+1=00000000
补码求原码
知一个数的补码,求原码的操作其实就是对该补码再求补码:
- ⑴如果补码的符号位为
0
,表示是一个正数,其原码就是补码。 - ⑵如果补码的符号位为
1
,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。
例:已知一个补码为11111001
,则原码是10000111(-7)
。
因为符号位为 1
,表示是一个负数,所以该位不变,仍为 1
。
其余七位 1111001
取反后为 0000110
;再加1,所以是10000111
。