冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数。在学习原码,反码和补码之前,需要先了解机器数和真值的概念。
一、机器数和真值
1、机器数
一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1。
比如,十进制中的数 +3,计算机字长为8位,转换成二进制就是00000011。如果是 -3,就是10000011。
那么,这里的00000011和10000011就是指机器数。
2、真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是-3而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值= +000 0001 = +1,1000 0001的真值=–000 0001 =–1
二、整数的表达
在java虚拟机中整数有byte、short、int、long四种分别表示 8位(1个字节)、16位(2个字节)、32位(4个字节)、64位(8个字节)有符号整数。 整数使用补码表示!
首先我们先了解一下原码和反码。
1. 原码
所谓原码就是符号位加上数字的二进制表示,int为例,第一位表示符号 (0正数 1负数)。
[+1]原 = 0000 0001
[-1]原 = 1000 0001
对于原码来说,绝对值相等的正数和负数只有符号位不同。
2. 反码
一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,(符号位不变化,其余位数取反)。
[+1]反 = 0000 0001
[-1]反 = 1111 1110
3. 补码
一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,反码加1就是补码。
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
栗子1:
已知一个负数 -99求补码步骤:
- 二进制原码表示
-99 原码:11100011
- 符号位不变化为1 求反码
-99 反码:10011100
- 符号位不变化,其余的加1
-99 补码:10011101
栗子2:
已知一个负数的补码 10011101,将其转换为十进制数,步骤:
- 先对各位取反
10011101,最高位为1,所以是负数,对各位取反得01100010
- 将其转换为十进制数
01100010,转换为十进制数得 98
- 加上负号,再减去1。
98,加上负号得 -98,再减1得 -99
三、浮点数的表达
在计算机中,浮点数主要分为单精度和双精度浮点。
主要有4个不同点:
- 在内存中占有的字节数不同
单精度浮点数占4个字节(32位)
双精度浮点数占8个字节(64位) - 有效数字位数不同
单精度浮点数有效数字8位
双精度浮点数有效数字16位 - 所能表示数的范围不同
单精度浮点的表示范围:-3.40E+38 ~ +3.40E+38
双精度浮点的表示范围:-1.79E+308 ~ +1.79E+308 - 在程序中处理速度不同
一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快
浮点数的表示和运算广泛遵循IEEE 754标准。
一个浮点数由三部分组成:符号位S、指数部分E(阶码)以及尾数部分M(如下)。
Float
S--------E-------M
1位-----8位-----23位
Double
S--------E-------M
1位-----11位----52位
栗子3:
浮点数:-5
1 10000001 01000000000000000000000
1:符号位 -1
10000001:指数位 2^7+1= 129
01000000000000000000000:尾数位:1.01 ,因为指数位不全为0,尾数附加位为1
-1*2^(129-127)*(2^0+2^-2) = -5
总结
- 正数:它的原码、反码、补码相同。
- 负数:反码——符号位不变化,其余位数取反; 补码——符号位不变化,反码+1
- 由补码计算数值:先区分正负数,正数可直接计算; 负数则 -1*(全部位取反后转为10进制) -1
- 补码的好处:可利用加法统一处理加减法,无需减法器操作
- 单、双精度浮点数的区别
练习
- 有关补码,简要阐述补码的好处。并计算给出 -105, 205 整数的补码。
- 补码 10010111,计算十进制整数值。
- 有关浮点数,根据IEEE 745,计算11000001101100000000000000000000的单精度浮点的值。