全网都在找的二进制?十六进制? 算法? [在这里~]

什么是2进制

2进制:逢2进1的计数规律

10进制
规则:逢10进1
数字:0 1 2 3 4 5 6 7 8 9
权:万 千 百 十 个
基数:10

在这里插入图片描述

2进制
规则:逢2进1
数字:0 1
权:128 64 32 16 8 4 2 1
基数:2

在这里插入图片描述

计算机为何采用2进制:成本低!

00000000 00000000 00000000 00000000 0
00000000 00000000 00000000 00000001 1
00000000 00000000 00000000 00000010 2
00000000 00000000 00000000 00000011 3
00000000 00000000 00000000 00000100 4
00000000 00000000 00000000 00000101 5
00000000 00000000 00000000 00000110 6
00000000 00000000 00000000 00000111 7
00000000 00000000 00000000 00001000 8
00000000 00000000 00000000 00001001 9
00000000 00000000 00000000 00001010 10
00000000 00000000 00000000 00001011 11
00000000 00000000 00000000 00001100 12
00000000 00000000 00000000 00001101 13
00000000 00000000 00000000 00001110 14
00000000 00000000 00000000 00001111 15

00000000 00000000 00000000 00110001 =32+16+1=49(10)
00000000 00000000 00000000 01100100 =64+32+4=100(10)

2进制转换为10进制:将包含1的位置权值求和
在这里插入图片描述

案例:

package demo;
​
public class Demo01 {
​
    public static void main(String[] args) {
        /*
         * 2进制
         */
        int n = 50;//"50"编译后 110010,n就是2进制的!
        //Integer.toBinaryString() 是Java提供的现成
        //静态方法,在Integer类上定义的工具方法
        //Binary: 2进制 toBinaryString:将计算机内存
        //中的int类型2进制存储情况做展示
        //toBinaryString 方法会自动省略高位的0
        System.out.println(Integer.toBinaryString(n));
        n++;
        System.out.println(Integer.toBinaryString(n));
        for(int i=0; i<=100; i++) {
            System.out.println(Integer.toBinaryString(i));
        }
        //输出0~100的2进制
        //从中抽取20个数,手工换算10进制数,自行验证
        
    }
​
}

什么是16进制

16进制
规则:逢16进1
数字: 0 1 2 3 4 5 6 7 8 9 a b c d e f
权:4096 256 16 1
基数:16

16进制:逢16进1的计数规律,计算机行业采用16进制,对2进制进行缩写。

在这里插入图片描述

如何使用16进制缩写2进制:

从2进制的最低位开始, 每4位2进制,对应缩写为1位16进制数。位数不够,高位可以补0.

在这里插入图片描述
案例:

package demo;public class Demo02 {public static void main(String[] args) {
        /*
         * 1. Java 7 提供2进制直接量书写格式 0b 为开头
         *    2进制直接量书写非常冗长繁琐
         * 2. 使用16进制简写2进制, 是常用方式
         *    0x 表示16进制
         *    0b 表示2进制
         */
        int n = 0b0011_0111_1110_0011_1111_1001_1010_0111;
        //        3    7    e    3    f    9    a    7
        int m = 0x37e3f9a7;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
    }
}

补码

补码: 计算机中处理负数的一种编码,设计目的是将固定位数2进制,分一半作为负数使用。因为其编码中正负数互补对称,故称为“补码”

补码编码分析:采用4位2进制数,
讨论补码的规律推广到32位数(int)补码

补码的编码规则:

1.采用固定位数编码,计算时候多出位数自动溢出
2.高位为0的是正数、高位为1是负数,最高位称为符号位,符号位参与计算
3.从0开始倒推负数编码在这里插入图片描述

案例:

public class Demo03 {public static void main(String[] args) {
        /*
         * int 类型,32位数, 的最大值,最小值编码
         * int 在内存中的编码是补码!
         */
        int max = Integer.MAX_VALUE; //int最大值
        int min = Integer.MIN_VALUE; //int最值
        System.out.println(max);
        System.out.println(min);
    
        System.out.println(Integer.toBinaryString(max));
        System.out.println(Integer.toBinaryString(min));    
    }}

负数的编码:

11111111111111111111111111111111 -1
11111111111111111111111111100111 =-1-8-16=-25
11111111111111111111111111101000 =-1-1-2-4-16=-24
11111111111111111111111111001101 =-1-2-16-32 =-51

经典面试题目:

如下代码输出结果是( B ):
System.out.println(~80+1);
A.-79 B.-80 C.-81 D.80

如下代码输出结果是( C ):
System.out.println(~80);
A.-79 B.-80 C.-81 D.80

如下代码输出结果是( B ):
System.out.println(~-80+1);
A.79 B.80 C.81 D.82

如下代码输出结果是( A ):
System.out.println(~-80);
A.79 B.80 C.81 D.82

2进制运算

运算符:

~取反 &与 |或
>>> 逻辑右移位
>> 数学右移位
<< 左移位

与计算 &

基本规则:逻辑乘法, 有0则0

0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1

在运算时候,将两个运算数据对齐位数,对应位计算与。

举个例子:

		 7   7    b   c    a   c    3   1   
n   =   01110111 10111100 10101100 00110001
m   =   00000000 00000000 00000000 11111111   mask 掩码
k=n&m   00000000 00000000 00000000 00110001

如上运算意义:是一种掩码(截取)计算,利用m将n的最后8位数截取保存到k中

代码:

int n = 0x77bcac31;
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));

在软件底层经常需要将int类型拆分为4个8位数(字节)

	  	  b1       b2       b3       b4
n =    01111011 11111000 01001010 10001110
b1=    00000000 00000000 00000000 01111011
b2=    00000000 00000000 00000000 11111000 
b3=    00000000 00000000 00000000 01001010
b4=    00000000 00000000 00000000 10001110

逻辑右移位计算 >>>

  • 运算规则:将数字整体向右移动,低位溢出, 高位补0

举个例子:

n =      01111011 11111000 01001010 10001110
m=n>>>1  001111011 11111000 01001010 1000111
k=n>>>2  0001111011 11111000 01001010 100011
g=n>>>8  00000000 01111011 11111000 01001010 
b3=(n>>>8) & 0xff;

代码:

int n = 0x7bf84a8e;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff;
int b3 = (n>>>8) & 0xff;
int b4 = n & 0xff;
//b1 b2 b4 ?
//按照2进制输出 n m k g b1 b2 b3 b4 

| 或运算

0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1

计算时候将两个数字对齐位数,对应的位置进行与计算

举个例子:

n   =    00000000 00000000 10111011 00000000
m   =    00000000 00000000 00000000 10111101
k=n|m    00000000 00000000 10111011 10111101

上述案例的意义:将n和m拼接为一个16位数

代码验证:

int n = 0xbb00;
int m = 0xbd;
int k = n | m;
//检验结果:按照2进制输出 n m k 

左移位计算 <<

2进制数字整体向左移动,高位自动溢出,低位补0, 注意
可能会发生符号位溢出。

举个例子:

n     =    00100110 11100000 10101001 01010110
m=n<<1     0100110 11100000 10101001 010101100
k=n<<2     100110 11100000 10101001 0101011000
g=n<<8     11100000 10101001 01010110 00000000 

验算代码:

int n = 0x26e0a956;
int m = n<<1;
int k = n<<2;
int g = n<<8;
//按照2进制输出 n m k g

将4个字节(8位、Byte)合并为一个int

b1= 00000000 00000000 00000000 01111011
b2= 00000000 00000000 00000000 11111000
b3= 00000000 00000000 00000000 01001010
b4= 00000000 00000000 00000000 10001110

b1<<24 01111011 00000000 00000000 00000000
b2<<16 00000000 11111000 00000000 00000000
b3<<8 00000000 00000000 01001010 00000000
b4= 00000000 00000000 00000000 10001110

n = (b1<<24)|(b2<<16)|(b3<<8)|(b4)

b1 b2 b3 b4
n = 01111011 11111000 01001010 10001110

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会乄假装

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值