二进制-了解计算机的源头

阿拉伯数字采取进位制法,高位在做,低位在右。十进制计数法,基于阿拉伯数字,十进制的数位全都是10^n的形式,这里的10称为十进制计数法的基数,这也就是十进制中“十”的由来。计算机中数据存放以二进制为主。二进制是使用2作为基数,它的位数也就是2^n的形式。

二进制与十进制之间转换

举例,二进制:110101

           十进制:1*2^5+1*2^4+0*2^3+1*2^2+0*2^1+1*2^0=53

由此可以推导出八进制、十六进制。

计算机为什么使用二进制?

这和计算机硬件有关,组成计算机系统的逻辑电路通常只有两个状态,即开关的接通和断开。断开用“0”表示,接通用“1”表示。因为只有这两种状态,即便系统在收到干扰是仍然可靠分辨出“0”和“1”,所有,再具体的系统实验中,二进制的数据表达具有抗干扰能力强,可靠性高的优点。

试想,用十进制或者更高的进制位涉及具有10种状态的电路,情况就显得很复杂了,判断状态时出错的几率大大提高了。

不仅在实际硬件电路上,而且在逻辑运算时,“真”“假”也只有2种状态,正好与二进制的“1”“0”对应。逻辑运算中的加法(“或”运算)、乘法(“与”运算)、否定(“非”运算)都可以通过“0”与“1”的加、乘、减来实现。

二进制的位操作

位操作:直接堆内存中的二进制进行操作。常见的二进制位操作包括向左移位和向右移位的移位操作,“或”、“与”、“异或”的逻辑操作。

向左移位

二进制110101向左移1位,就是在末尾添加一位0。

110101  ->  1101010

进行移位操作有可能会发生数字溢出的情况。所谓数字溢出,就是二进制数的位数超过了系统所指定的位数。现在一般主流系统都支持32位整型数字。如果移位操作发生了数字溢出,就需要将溢出的位数去除。

计算一下向左移位前后两个数的十进制数值,之前是53,向左移位后是106。由此可得,二进制左移一位,实际上就是十进制数字翻一倍。

向右移位

二进制110101向右移1位,就是去除末尾的那一位。

110101  ->  11010

计算一下向右移位前后两个数的十进制数值,之前是53,向左移位后是26,这正好是53除以2的整数商。由此可得,右移一位就是将数字除以2求得的整数商的操作。

在Java中代码实现移位操作

import java.math.BigInteger;
public class demo{
    public static int leftShift(int num,int m){
        return num << m;
    }
    public static int rightShift(int num,int m){
        return num >>> m;
    }
}

可见左移右移明显不一样,那为什么右移时不是 “>>”n呢?

这是因为java的二进制数值中最高一位是符号位,当符号位为0,表示该数值的整数,当符号位为1时,表示该数值为负数。

以32位Java为例,我们来看一下53、-53

这里-53用的补码形式

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

补码计算规则:

        正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同。

        负整数的符号位固定为1,由原码变为补码时,规则如下:

               1、原码符号位1不变,整数的每一位二进制数位求反,得到反码

               2、反码符号位1不变,反码数值位最低位加1,得到补码

负整数在进行右移时就会出现是否移动符号位的问题?

这就出现了两种右移。

  1. 逻辑右移:右移一位,左边补位
  2. 算术右移:符号位不动,其他右移,空出来的补1

位的“或”

二进制的“1”和“0”对应逻辑中的“真”和“假”,可以针对位进行逻辑操作。逻辑“或”:参与操作的位中只要有一个位是1,那最终结果就是1,即为真。

位的“与”

参与操作的位中必须全都是1,那最终结果为1,即为真。

位的“异或”

参与操作的位相同,那结果就是0,否则就是1.所谓“异或”中的“异”,也就是要参与操作的位不同,才能得到“真”的结果。

 

猜你喜欢

转载自blog.csdn.net/bertZuo/article/details/84999973
今日推荐