一、机器值和真值
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
3.原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。原码取值范围:【11111111,011111111】即【-127,127】
4.反码
正数的反码是其本身。
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
5.补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
深入了解
注:
机器都是使用补码,运算也是使用补码。
正数的原码、补码、反码都一样。
补码与原码相互转换,其运算过程是一样的。
1.左移运算符
左移的规则只记住一点:丢弃最高位,0补最低位
左移一位相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
运算方式:数值的补码全部往左移动X位,符号位和最高位都舍弃,最低位补0。
正数:
int a = 5 ;
int b = a << 2 ;(5*22=20)
[ 0000 0000 0000 0000 0000 0000 0000 0101 ] 5的补码
[ 0000 0000 0000 0000 0000 0000 0001 0100 ] 对于正数而言,反码就是原码,即 20
负数:
int a = -5 ;
int b = a << 2 ;(-5*22=-20)
[ 1000 0000 0000 0000 0000 0000 0000 0101 ] -5的原码
[ 1111 1111 1111 1111 1111 1111 1111 1010 ] -5的反码
[ 1111 1111 1111 1111 1111 1111 1111 1011 ] -5的补码
[ 1111 1111 1111 1111 1111 1111 1110 1100 ] a<<2左移2位
将补码转换成原码就可以得到数值,补码转原码和原码转补码一样,符号位不变,其余位取反加一。
[ 1000 0000 0000 0000 0000 0000 0001 0011 ]
[ 1000 0000 0000 0000 0000 0000 0001 0100 ] 得到a<<2的原码,即 -20
2.右移运算符
右移的规则只记住一点:符号位不变,左边补上符号位。
右移一位相当于除以2的1次方,右移n位就相当于除以2的n次方。
运算方式:数值的补码向右移X位,符号位不变(左边补上符号位)。
与左移差不多,这里就不列出具体案例了。
3.无符号右移
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位
无符号右移规则和右移运算是一样的,只是填充时不管左边的数字是正是负都用0来填充,无符号右移运算只针对负数计算,因为对于正数来说这种运算没有意义
用移位操作可以极大地提高性能,因为在计算机底层对位的操作是最快。
有些是自己写的,有些是COPY的,方便以后的查看。