1 计算计中的数据与二进制 1.1 数据

计算机中的数据总是以二元状态存在的,通常用0或1两种符号来表示,它也方便用于表示电路中的高低电平。

1.2 二进制

在计算机中是用二进制来表示数据的。二进制中1=1,2=10,4=100,8=1000。生活中,我们用得比较多的就是10进制,那么要怎么把10进制与2进制进行转换呢?

十进制转换成二进制

程序员二进制计算器怎么用(程序员必须了解的计算机基础之二进制)(1)

10进制转换成二进制

二进制转换成十进制

程序员二进制计算器怎么用(程序员必须了解的计算机基础之二进制)(2)

二进制转换成十进制

2 原码、反码和补码

在计算机中,最小的单位是位(bit),也就是二进制中的每一个数值,最小的数据存储单位是字节(byte)。一个字节由8位组成,这8位中最左侧的一位是符号位,0表示正数,1表示负数。

2.1 原码

原码就是数据的实际值,如1的原码为 0000 0001,-2的原码为1000 0010,0的原码为0000 0000。8位二进制数能表示的最大范围是[-127,127]。

2.2 反码

正数的反码是原码本身,负数的反码是在原码的基础上,符号位不变,其余位取反,如1的原码是0000 0001,反码也是0000 0001;-2的原码为1000 0010,反码为1111 1101。8位二进制数能表示的最大范围是[-127,127]。

2.3 补码

正数的补码是原码本身,负数的补码是原码的基础上符号位不变,其余位取反然后加1。8位二进制数能表示的最大范围是[-128,127]。

【注:0的原码、反码、补码是同一个!】

2.4 计算计中补码参与运算

1 (-2) = -1,对应的原码为 0000 0001 1000 0010 = 1000 0011 = -3, 这是不正确的。

对应的反码为 0000 0001 1111 1101 = 1111 1110,转换成原码 1000 0001=-1,正确。

如果 1-1用反码计算的话,0000 0001 1111 1110 = 1111 1111,转换成原码就是1000 0000 = -0,是错误的表示。

所以如果用补码来计算0000 0001 1111 1111 = 0000 0000,对应的原码也是0000 0000=0,正确。在补码中1000 0000表示-128。

2.5 溢出

-35 -128用补码参与运算结果是多少?

程序员二进制计算器怎么用(程序员必须了解的计算机基础之二进制)(3)

溢出

如图,计算结果超出了8位,实际结果应该是-163,但是8位能表示的范围是[-128, 127],所以上面的计算结果溢出了。取后8位即为溢出的结果93。

通过代码表示:

public static void main(String[] args) { byte b1 = (byte) -35; byte b2 = (byte) -128; byte b3 = (byte) (b1 b2); // 这里的结果是93 System.out.println("b3 = " b3); // 这里也是93 System.out.println(127 - 35 1); }

溢出后的结果遵循这个规则,如果-128向下溢出1位,结果是127,溢出2位,结果是126,以此类推,-128溢出35,结果就是93。同理,127向上溢出1位就是-128。

2.6 单位及换算

1B = 8b

1KB = 1024B

1MB = 1024KB

1GB = 1024MB

3 位运算3.1 按位与运算(&)

按位与的运算规则是:相同位都为1则为1,否则为0;

举例:

1:原码:0000 0001,反码:0000 0001,补码:0000 0001;

3:原码:0000 0011,反码:0000 0011,补码:0000 0011;

所以:0000 0001 & 0000 0011 = 0000 0001,即 1 & 3 = 1;

1:原码:0000 0001,反码:0000 0001,补码:0000 0001;

-3:原码:1000 0011,反码:1111 1100,补码:1111 1101;

所以:1111 1101 & 0000 0001 = 0000 0001,对应的原码为0000 0001,即1 & -3 = 1;

-1:原码:1000 0001,反码:1111 1110,补码:1111 1111;

-2:原码:1000 0010,反码:1111 1101,补码:1111 1110;

所以:1111 1101 & 1111 1110 = 1111 1100,对应的原码为1000 0010,即-1 & -2 = -2;

3.2 按位或运算(|)

按位或的运算规则是:相同位只要有一个为1则为1,否则为0。

举例:

1:原码:0000 0001,反码:0000 0001,补码:0000 0001;

3:原码:0000 0011,反码:0000 0011,补码:0000 0011;

所以:0000 0001 | 0000 0011 = 0000 0011,即 1 & 3 = 3;

3.3 按位异或(^)

按位异或的运算规则是:相同位相同则为0,不同则为1。

举例:

1:原码:0000 0001,反码:0000 0001,补码:0000 0001;

3:原码:0000 0011,反码:0000 0011,补码:0000 0011;

所以:0000 0001 ^ 0000 0011 = 0000 0010,即 1 & 3 = 2;

3.4 右移运算(>>)

右移规则:符号位不变,低位(0)补齐,符号位补移出的高位(1)。

举例:

- -3 >> 5:

-3:原码:1000 0011,反码:1111 1100,补码:1111 1101;

1111 1101,右移5个,1000 0111,符号位补高位1111 1111,对应的原码1000 0001,即-3 >> 5 = -1。

- 3 >> 5

3:原码:0000 0011,反码:0000 0011,补码:0000 0011;

0000 0011右移5个,0000 0000,符号位补高位,结果还是0000 0000,即 3 >> 5 = 0;

3.5 左移运算(<<)

左移规则:符号位不变,低位补齐。

举例:

-3 << 5:

-3:原码:1000 0011,反码:1111 1100,补码:1111 1101;

1111 1101左移5位,1010 0000,对应的反码是1001 1111,原码是1110 0000,即-3 << 5 = -96。

,