API 基础第三天—二进制

API 基础第三天—二进制

一、什么是二进制

逢2进一的计数规则

2进制

规则:逢2进1

数字:0 1 2 3 4 5 6 7 8 9

权:万 千 百 十 个

基数:10

计算机为撒是二进制?便宜!!!成本明显优势!!!

如何将2进制转换为10进制:将1位置对应权值累加求和

二、什么是16进制

  • 逢16进1的计数规则
  • 2进制书写非常繁琐,16进制的计数是2进制的基数4次方,2进制每4为数可以缩写为1个16进制
案例:
package lastday;

public class Demo02 {
    public static void main(String[] args) {
        /**
         * 2进制与16进制
         * -java7提供了2进制字面量前缀 0b
         * -可以在数字中添加下划线,不影响数值
         * -16进制缩写二进制非常方便
         * -从2进制的最低开始,每四位缩写为1位16进制数
         * -计算机内部没有10进制,没有16进制,只有二进制
         */
        int n = 0b110010;//32+16+2=50;
        System.out.println(n);//输出的时候自动把2进制转换为了10进制
        n = 0b1010_1010_0101;//不影响数值
              //a    a    5   16进制
        System.out.println(n);//十进制2725
        n = 0xaa5;
        System.out.println(Integer.toBinaryString(n));//二进制输出,此方法默认高位0省略
        System.out.println(n);//十进制2725

    }
}

三、补码

在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

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

1. 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

反码的表示方法是:

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

补码的表示方法是:

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.

  • 原码公式:- 2 n-1–1 ~+ 2 n-1 –1
  • 补码公式:- 2 n-1 ~+ 2 n-1 –1

计算机中一种表示有符号数编码,其核心思想就是将固定2进制分一半作为负数。

如何将固定位数2进制分一半作为负数?

  • 以四位二进制讲解如何设计补码
  • 计算时保持4为不变,多余位自动溢出
  • 最高位称为符号位,0是正数,1是负数

在这里插入图片描述

11111111111111111111111111111111 = -1
11111111111111111111111111111101 = -1-2//...64 32 16 8 4 2 1
11111111111111111111111111111001 = -1-2-4//减去的是权数
手工计算负数的值:计算这个数比-10位置的权

4.互补对称

在这里插入图片描述

-n = ~n+1//取反加1
11111111 11111111 11111111 11111001 = -1-2-34 = -7
00000000 00000000 00000000 00000110 = 2+4=6
00000000 00000000 00000000 00000111 = 1+2+4=7    

四、2进制运算

运算符号:

~取反
&| 或运算
>>>右移位运算
<<<左移位运算

1.&运算

0 & 0  0
0 & 1  0
1 & 0  0
1 & 1  1
//有0结果就是0

运算时将两个2进制对其为,对应位置进行与运算

n  =  00010111 10011101 01011101 10011110
m  =  00000000 11111111 00000000 00000000
k=n&m 00010111 10011101 00000000 00000000
意义:k中存储的是n的最后8位数,如上运算叫掩码(mask)运算,m成为mask(掩码)。
package lastday;

public class Demo06 {
    public static void main(String[] args) {
        /**
         * 掩码运算
         * 4位掩码:0xf 0b1111 15
         * 6位掩码:0x3f 0b111111 63
         * 
         */
        int n = 0x179d5d9e;
        int m = 0xff;
        int k = n & m;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        /**
         * 00010111 10011101 01011101 10011110
         *                            11111111
         *                            10011110
         */
    }
}

2.右移位运算

运算规则;将二进制数整体向右移动,低位自动溢出舍弃,高位补0

n     =   01100111 11010111 10001111 01101101
m=n>>>1   00110011 11101011 11000111 10110110//右移了一位
package lastday;

/**
 * 右移位运算
 */
public class Demo07 {
    public static void main(String[] args) {
        int n = 0x67d78f6d;
        int m = n >>> 1;
        int k = n >>> 2;
        int g = n >>> 8;
        int b3 = (n >>> 8) & 0xff;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        System.out.println(Integer.toBinaryString(g));
        System.out.println(Integer.toBinaryString(b3));
        /**
         * 将一个整数拆分为4个字节
         * 01100111  11010111  10001111  01101101
         * 00110011  11101011  11000111  10110110
         * 00011001  11110101  11100011  11011011
         * 00000000  01100111  11010111  10001111
         * 10001111
         */
    }
}

将一个数拆分位4个字节
int n = 0x179d5d9e;
int b1 = (n >>> 24) && 0xff;
int b1 = (n >>> 16) && 0xff;
int b1 = (n >>> 8) && 0xff;
int b1 = n && 0xff;

3.|运算

基本运算规则:逻辑加法

0 | 0 0
0 | 1 1
1 | 0 1
1 | 1 1
//有1结果就是1

运算时候两个2进制数对齐,对应位进行或运算

例子:
n  =   00000000 00000000 00000000 11011101
m  =   00000000 00000000 10011101 00000000
k=n|m  00000000 00000000 10011101 11011101
//在与运算中,只要有1结果就是1
意义:
两数错位合并
package lastday;
/**
*或运算
*/
public class Demo08 {
    public static void main(String[] args) {
        int n = 0xdd;//11011101
        int m = 0x9d00;//10011101 11011101
        int k = n | m;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        /**
         * 00000000  00000000  00000000  11011101
         * 00000000  00000000  10011101  00000000
         * 00000000  00000000  10011101  11011101
         */

    }
}

4.左移位运算

2进制数字整体向左移动,高位自动溢出,低位补0。和右移相反

将四个字节合并位一个整数
b1  =  00000000 00000000 00000000 00010111
b2  =  00000000 00000000 00000000 10011101
b3  =  00000000 00000000 00000000 01011101
b4  =  00000000 00000000 00000000 10011110


n = (b1<<24) | (b2<<16) | (b3<<8) | b4;
int b1 = 0x17;
int b2 = 0x9d;
int b3 = 0x5d;
int b4 = 0x9e;
int n = (b1<<24) | (b2<<16) | (b3<<8) | b4

意义:

16 8 4 2 1
     1 0 1 = 5
   1 0 1   =10//向左移动1位  *2
 1 0 1     =15//向左移动两位  *2*2  
package lastday;

public class Demo09 {
    public static void main(String[] args) {
        int n = 5;
        System.out.println(n<<1);
        System.out.println(n<<2);
        System.out.println(n<<3);
        /**
         * 10
         * 20
         * 30
         */
    }
}

5.>>>和>>的区别

>>>逻辑右移位:数字向右移动,低位自动溢出,高位补0,结果没有数学意义。如果仅仅将数位向右移动,不考虑数学意义,则使用>>>
>>数学右移位:数学向右移动,低位自动溢出,正数高位补0,负数高位补1,移动一次数学除于2,小方向去整数
n  =     11111111 11111111 11111111 11001100 = -1-1-2-16-32=-52
m=n>>1   11111111 11111111 11111111 11100110=-1-1-8-16=-26
k=n>>2   11111111 11111111 11111111 11110011=-1-4-8=-13
g=n>>3   11111111 11111111 11111111 11001=-1-2-4=-7//往小取整
//逻辑右移
n>>>1    01111111 11111111 11111111 11100110=?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值