二进制转为十进制
二进制1101.11
1=1
10=2
100=4
1000=8
10000=16
0.1=2^-1=0.5 (负次方为正次方的倒数)
0.01=2^-2=0.25
1101.11=8+4+0+1+0.5+0.25=13.75
源码、反码、补码
一个有符号定点数的最高位为符号位,0是正,1是负
例如,0000001 就是+1,1000001 就是-1
正数的反码和补码都是和原码相同
负数的反码是将其原码除符号位之外的各位求反
源码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111],即:
[-127 , 127]
原码是人脑最容易理解和计算的表示方式.
反码
反码的表示方法是:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算。
补码(即在反码的基础上+1)
补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
为什么有源码、补码、反码
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) =
[00000001]原 + [10000001]原 =
[10000010]原 = -2
为了解决原码做减法的问题, 出现了反码。
1-1=0
1 - 1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反 = [1000 0000]原
= -0
-0 没有意义,补码的出现就是解决编码问题
1-1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]补 + [1111 1111]补
= [0000 0000]补
=[0000 0000]原
位运算
按位与:两个都是 1 就是 1
9 & 5
1001 = 9
0101 = 5
0001 = 1
按位或: 有一个(允许2个)为 1 就是 1
9 | 5
1001 = 9
0101 = 5
1101 = 13
按位抑或:不一样的就是 1
9 ^ 5
1001 = 9
0101 = 5
1100 = 12
按位同或:一样的就是 1(无论为1还是0)
9 ^ 5
1001 = 9
0101 = 5
0011 = 3
左移运算
左移运算符m<<n表示吧m左移n位。左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0.比如:
00001010 << 2 = 00101000
10001010 << 3 = 01010000
右移运算
右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要稍微复杂一点。这里要特别注意,如果数字是一个无符号数值,则用0填补最左边的n位。如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说如果数字原先是一个正数,则右移之后再最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1.下面是堆两个8位有符号数作右移的例子:
00001010 >> 2 = 00000010
10001010 >> 3 = 11110001
关于移位的运算有这样的等价关系:把整数右移一位和把整数除以2在数学上是等价的。
a << = 1 ; //a左移一位等效于a = a * 2;
a << = 2 ; //a左移2位等效于a = a * 2的2次方(4);