ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二进制你了解多少?

2021-08-24 13:33:10  阅读:463  来源: 互联网

标签:进制 二进制 System 00000000 int 了解 println 多少 out


2进制

2进制

什么是2进制

逢2进1的计数规则

案例:

public class Demo01 {
    public static void main(String[] args) {
        /*
         * 2进制
         * - Java 先编译后运行
         * - Java 再编译期间,将10进制字面量编译为2进制
         * - Java 输出时候将2进制转换为10进制输出
         * - Java API Integer.toBinaryString() 
         *   可以输出2进制内容
         * - toBinaryString()输出时候自动省略了高位0
         */
        int i = 50; //编译后 110010 运行时候 110010
        System.out.println(i); 
        //输出时候110010 转换为 "50" 再输出
        System.out.println(Integer.toBinaryString(i)); 
        //110010
        //输出0~200的2进制,研究其值
        for(int n = 0; n<=200; n++){
            System.out.println(Integer.toBinaryString(n));
        }
    }
}

0~200的2进制

如何将2进制正数转换为10进制: 将每个1位的权值进行累加

00000000 00000000 00000000 00000000 = 0
00000000 00000000 00000000 00000001 = 1
00000000 00000000 00000000 00000010 = 2
00000000 00000000 00000000 00000011 = 2+1 = 3
00000000 00000000 00000000 00000100 = 4
00000000 00000000 00000000 00000101 = 4+1=5
00000000 00000000 00000000 00000110 = 4+2=6
00000000 00000000 00000000 00000111 = 4+2+1=7
00000000 00000000 00000000 00001000 = 8
00000000 00000000 00000000 00001001 = 8+1 = 9
00000000 00000000 00000000 00001010 = 8+2 = 10
... ...
00000000 00000000 00000000 00100101 = 32+4+1=37
... ...
00000000 00000000 00000000 00101011 = ?

自己动手练习练习: 输出0~200之间的2进制, 随机抽取20个数, 手工计算10进制值,自己编程验证.!

16进制

逢16进1的计数规则

16进制用于缩写2进制, 用于简化2进制!

  • 2进制书写非常繁琐, 容易错误
  • 利用16进制, 从2进制最低位开始, 每4位缩写为一个16进制数. 缩写后使用方便!
public class Demo02 {
    public static void main(String[] args) {
        /*
         * 2进制书写繁琐
         * - Java 7 开始提供了2进制直接量前缀 0b
         * - 在数字中使用下划线分割不影响数值
         * - 利用16进制缩写,可以简化2进制
         *   从最低位开始, 每4位缩写为一位16进制
         */
        int n = 100; //1~9开头的数字是10进制直接量
        int m = 0b100; //0b开头, 则表示是2进制
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        n = 0b100_11111100_01110001_01011111;
        //    4   f   c    7   1    5   f
        m = 0x4fc715f;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        //任意编写5组32位2进制数, 利用16进制缩写, 自己输出验证
    }
}

8进制

利用8进制可以对2进制进行3位3位缩写,

从2进制最低位开始, 每3位缩写为一位8进制.

  • 缩写不算方便, 没有16进制缩写的短
  • 8进制数字 0~7
  • Java中8进制前缀是 0, 这个经常在考试中出现

如:

int n = 080;
System.out.println(n);

上述代码输出结果 ( D ): A.080 B.80 C.100 D.编译错误

补码(数字编码规则)

什么是补码

补码是计算机中用于处理有符号(正数和负数)数的一种底层编码规则.

  • 补码编码思路: 将固定位数的2进制数, 分一半作为负数使用.
  • 补码计算时候会自动溢出: 超过固定位数的数字自动舍弃.

利用4位2进制数讨论补码编码原理, 然后推广到32位int类型.

分析: 如何设计 4 位补码

案例:

public class Demo03 {
    public static void main(String[] args) {
        /*
         * 补码的编码规律
         * Binary: 2进制
         * Integer: 整数
         */
        int n = -3;
        System.out.println(Integer.toBinaryString(n));
        //max 最大  value 值
        int max = Integer.MAX_VALUE;
        int min = Integer.MIN_VALUE;
        System.out.println(max); //  2147483647
        System.out.println(min); // -2147483648
        System.out.println(Integer.toBinaryString(max));
        System.out.println(Integer.toBinaryString(min));

        n = -1;
        System.out.println(Integer.toBinaryString(n));

        long lmax = Long.MAX_VALUE;
        long lmin = Long.MIN_VALUE;
        long l = -1L;
        System.out.println(Long.toBinaryString(lmax));
        System.out.println(Long.toBinaryString(lmin));
        System.out.println(Long.toBinaryString(l));
        
    }
}

负数的编码规律

  • 首先记住-1的编码
  • 研究一个负数(最高位是1),检查这个数比-1少多少
                            8421
11111111111111111111111111111111 =-1
11111111111111111111111111111101 =-1-2=-3
11111111111111111111111111111001 =-1-2-4=-7
11111111111111111111111111100110 =-1-1-8-16=-26

输出-200到0的编码,随机挑选20个数字, 手工计算负数值, 自己演算结果。

/*
 * 研究负数的编码
 */
for(int i=-200; i<0; i++){
    System.out.println(Integer.toBinaryString(i));
}

补码的互补对称现象

补码编码结果有一个巧合,正负数互补对称, 因为互补对称, 称作补码。

互补对称公式: -n = ~n + 1, 最小值除外

面试题目1:

System.out.println(~100+1);

上述代码输出结果是( C )

A. -98 B.-99 C.-100 D.-101

面试题目2:

System.out.println(~100);

上述代码输出结果是( D )

A. -98 B.-99 C.-100 D.-101

面试题目3:

System.out.println(~-100);

上述代码输出结果是( B )

A.98 B.99 C.100 D.101

2进制运算

运算符号:

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

& 与计算

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

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

运算时候, 将两个整数对齐位数, 对应的位进行与运算:

举个例子:

           7   7    8   3    6   5    a   b 
n =       01110111 10000011 01100101 10101011
m =       00000000 00000000 00000000 11111111 
k = n&m   00000000 00000000 00000000 10101011

如上案例的意义:k中存储的是数字n的最后8位数。 m是一个用于切分n的一个“掩码(Mask)”,按照1的个数称为 x 位掩码。

程序:

int n = 0x778365ab;
int m = 0xff;
int k = n & m;
//按照2进制输出 n m k 

>>> 右移位运算

运算规则: 将2进制数位整体向右移动,地位自动溢出,高位补0

举个例子:

n =        01111110 00010111 01111100 01110111
m = n>>>1  001111110 00010111 01111100 0111011
k = n>>>2  0001111110 00010111 01111100 011101
g = n>>>8  00000000 01111110 00010111 01111100
b3= (n>>>8) & 0xff;

程序:

int n = 0x7e177c77;
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;
//按照2进制输出  n m k g b3

| 或运算

运算规则,逻辑加法, 有1则1:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

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

n   =    00000000 00000000 00000000 10111011
m   =    00000000 00000000 11110111 00000000
k = n|m  00000000 00000000 11110111 10111011 

上述案例的意义:错位合并两个8位数!

案例:

int n = 0xbb;
int m = 0xf700;
int k = n|m;
//检查 n m k 

<< 左移位运算

规则: 将2进制数整体向左移位,移动以后高位溢出, 低位补0

例子:

n  =      01011101 11111110 00001010 10111010
m = n<<1  1011101 11111110 00001010 101110100
k = n<<2  011101 11111110 00001010 1011101000

案例:

int n = 0x5dfe0aba;
int m = n<<1;
int k = n<<2;

移位运算是数学意义

2进制时候,数字整体向左移动一次, 数值扩大2倍。

案例:

int n = 5;
System.out.println(n<<1); //10
System.out.println(n<<2); //20
System.out.println(n<<3); //40

右移位的区别

>>> 逻辑右移位运算, 无论正负,低位自动溢出,高位补0, 仅仅在逻辑上将数字向右移动, 不关心是否是数学除以2的结果。

>> 数学右移位运算,移位时候低位自动溢出, 正数时候高位补0, 负数时候高位补1,结果是数学除以2,向小反向取整数的结果

举个例子,负数时候:

n  =    11111111 11111111 11111111 11001110 =-1-1-16-32=-50
m=n>>1  111111111 11111111 11111111 1100111 =-1-8-16=-25
k=n>>2  1111111111 11111111 11111111 110011 =-1-4-8=-13
g=n>>>1 011111111 11111111 11111111 1100111 =?

用法:

  • 如果用于替代 数学除以2 时候使用 >>
  • 如果用于将2进制数整体向右移位,不关心数学结果,使用 >>>

经典面试题目:

  • 将n * 8 可以替换(优化)为 ( n<<3 )
  • 将n / 2 可以替换(优化)为 ( n>>1 )

拆分合并整数

为何需要对整数进行拆分合并:

  • 互联网按照字节(8位)为单位传输数据
  • 任何数据都需要拆分为 字节(8位) 数据进行传输: 编码
    • 整数:32位需要拆分为 4字节
    • long:64位需要拆分为 8字节
    • ... ...
  • 收到数据时候, 再将字节组合为数据:解码

整数的拆分(编码):

             b1       b2       b3       b4 
n    =    01111011 11110000 11011100 00111101
b1   =    00000000 00000000 00000000 01111011
b2   =    00000000 00000000 00000000 11110000
b3   =    00000000 00000000 00000000 11011100
b4   =    00000000 00000000 00000000 00111101

int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff;
int b3 = (n>>>8) & 0xff;
int b4 = n & 0xff;

整数的解码(合并):自己编写代码进行测试

b1   =    00000000 00000000 00000000 01111011
b2   =    00000000 00000000 00000000 11110000
b3   =    00000000 00000000 00000000 11011100
b4   =    00000000 00000000 00000000 00111101
n    =    01111011 11110000 11011100 00111101

b1<<24    01111011 00000000 00000000 00000000 
b2<<16    00000000 11110000 00000000 00000000 
b3<<8     00000000 00000000 11011100 00000000
b4<<0     00000000 00000000 00000000 00111101

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

作业:该你自己动手啦

将一个 long 类型整数拆分为 8个字节。

将8个 字节合并为一个long 类型整数。

检查long类型的最大值,最小值和-1,-3

标签:进制,二进制,System,00000000,int,了解,println,多少,out
来源: https://www.cnblogs.com/zhang-xiangping/p/15179884.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有