博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2进制,10进制,16进制,补码和移位
阅读量:5297 次
发布时间:2019-06-14

本文共 5225 字,大约阅读时间需要 17 分钟。

逢二进一,逢十进一,十六进制

10110101(2)  = 128+32+16+4+1 = 181(10)   b   5(16) = b*16+5 = 11*16+5 = 181(10)

2进制

int n = 45;System.out.println(Integer.toBinaryString(n));

计算机的内部(Java)只有2进制数据, 在显示的时候编程语言提供API将2进制转换为10进制显示出来.

计算机只能处理2进制数据, 利用编程语言提供的算法支持了10进制

Java中用于支持2进制两个算法(方法):

  1. Integer.toString() 将内存2进制数据转换为10进制输出
  2. Integer.parseInt() 将10进制字符串转换为2进制数据

    int n = Integer.parseInt("22271"); System.out.println(Integer.toString(n));//"22271"

计算机"表面上"支持了10进制

2进制的计数原理

逢2进1的计数规则.

2进制原理

 

 

4位数2进制全排列

如:

84210000   00001   10010   20011   30100   40101   50110   60111   71000   81001   91010  101011  111100  121101  131110  141111  15

Java 验证代码:

for(int i=0; i<16; i++){    System.out.println(Integer.toBinaryString(i));}

如何将2进制转换为10进制

将2进制每个数字代表的1的个数进行求和即可:

10111101(2)=32+16+8+4+1(10)=128+32+29             =128+61=189(10)

Java 代码验证:

System.out.println(Integer.toBinaryString(189));

案例, 将2进制转换为10进制:

11010101(2)       10011011(2) =?(10)            =?(10) 10101101(2)       11101101(2)=?(10)            =?(10)

案例: 10进制转换为2进制

128 64 32 16 8 4 2 1183(10) =   1  0  1  1 0 1 1 1(2)           55    23  7   3 1 0        = 10110111(2)234(10) = ?(2)209(10) = ?(2)200(10) = ?(2)199(10) = ?(2)

为啥要用2进制

计算机采用2进制作为计算数据, 其成本最优!

使用2进制

16进制

用于简写2进制(缩写2进制), 原因是2进制的书写过于冗长, 2进制的每4位缩写为一个16进制数. 按照这个规则可以将2进制简写.

01011111 11011101 11011011 00010010 (2)   5   f    d   d    d   b    1   2 (16)

16进制与2进制的对应关系

2进制 16进制    0000   00001   10010   20011   30100   40101   50110   60111   71000   81001   91010   a1011   b1100   c1101   d1110   e1111   f

案例: 验证16进制与2进制的对应关系

10110101(2)  = 128+32+16+4+1 = 181(10)   b   5(16) = b*16+5 = 11*16+5 = 181(10)

验证:

int n = 0xb5;System.out.println(Integer.toBinaryString(n)); System.out.println(n);

编程时候凡是需要书写2进制数据时候, 都采用16进制作为缩写!!

补码

是一种利用"正数"表示"负数"的"算法", 节省了硬件成本!!!

4位数补码原理:

任何计算超过4位数自动溢出舍弃

0000    0001    0010    0011    0100    0101    0110    0111    1000    1001    1010    1011    1100    1101    1110    11110000     00010010...

 

案例:

for(int i=-10; i<10; i++){    System.out.print(Integer.toString(i)+" ");    System.out.println(Integer.toBinaryString(i));}

补码规律(int):

  1. 0 是 32位0
  2. -1 是 32位1
  3. max 是 01111111 11111111 11111111 11111111
  4. min 是 10000000 00000000 00000000 00000000

补码面试题:

System.out.println(Integer.MIN_VALUE-Integer.MAX_VALUE);选择如上代码的运行结果:  A. 2147483647 B.-2147483648 C.4294967296 D.1 E.-1

补码面试题:

System.out.println(Integer.MIN_VALUE-1);选择如上代码的运行结果:  A. 2147483647 B.-2147483648 C.4294967296 D.1 E.-1

补码面试题:

System.out.println(~88);选择如上代码的运行结果:  A. 88 B.-88 C.89 D.-89 E.98

2进制的运算符

~ 取反

>>> >> << 移位运算

& | 与 或 运算

>>> 逻辑右移位运算

运算规则: 将数字向右移动,高位补充0, 低位溢出舍弃

n = 01101101 00010001 11001001 10011011m = n>>>1m = 001101101 00010001 11001001 1001101k = n>>>2k = 0001101101 00010001 11001001 100110

验证:

int n = 0x6d11c99b;int m = n>>>1;int k = n>>>2;//...System.out.println(Integer.toBinaryString(n));System.out.println(Integer.toBinaryString(m));System.out.println(Integer.toBinaryString(k));

<< 逻辑右移位运算

运算规则: 将数字向左移动,低位补充0, 高位溢出舍弃

n = 01101101 00010001 11001001 10011011m = n<<1m = 1101101 00010001 11001001 100110110k = n<<2k = 101101 00010001 11001001 1001101100

验证: 略

移位运算的数学意义

引子:

移动小数点运算:

数据  33128. 右移动小数点一次结果 331280. 原始数据乘以10假设小数点不动,则数字向左移动,数字向左移动一次原始数据乘以基数(10)一次2进制同样有效

举个栗子:

n = 00000000 00000000 00000000 01100100.  //100m = n<<1;m = 0000000 00000000 00000000 011001000.     //200k = n<<2;k = 400

验证:

int n = 100;int m = n<<1;int k = n<<2;System.out.println(n);//100System.out.println(m);//200System.out.println(k);//400

>>> 与 >>

>>> 向右移动, 高位永远补0, 负数时候不符合数学除法规律 >> 数位向右移动, 高位为1(负数) 则补1, 高位为0(正数) 则补0, 保持符号位不变, 其结果符合数学除法规律(自动向小方向取整)

案例:

int n = -36;int m = n>>1;//m = -18int k = n>>>1; //? 不符合数学规律System.out.println(Integer.toBinaryString(n));System.out.println(Integer.toBinaryString(m));System.out.println(Integer.toBinaryString(k));

& 与运算

逻辑乘法

1 & 1 = 10 & 1 = 01 & 0 = 00 & 0 = 0

计算规则: 两个数上下对齐, 对应位数进行与计算

n = 01100011 00100110 00110111 11011110 m = 00000000 00000000 00000000 11111111  maskk = n&m;k = 00000000 00000000 00000000 11011110

代码:

//掩码运算int n = 0x632637de;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));

经典用途: 截取一个数据的后8位, 称为"掩码(mask)"运算

移位运算的用途

与掩码运算配合, 将数据进行拆分:

//将int n 拆分为 4个 8位数 b1 b2 b3 b4 int n = 0x632637de;int m = 0xff;int b1 = n&m;int b2 = (n>>>8) & m;int b3 = (n>>>16) & m;int b4 = (n>>>24) & m;

| 或运算 : 将数据进行合并

规则类似 加法

1 | 1 = 10 | 1 = 11 | 0 = 10 | 0 = 0

上下对齐计算或

案例:

b1= 00000000 00000000 00000000 10011101b2= 00000000 00000000 00000000 01101111b3= 00000000 00000000 00000000 11101111b4= 00000000 00000000 00000000 00110011n = (b1<<24)|(b2<<16)|(b3<<8)|b4    10011101 00000000 00000000 00000000     00000000 01101111 00000000 00000000     00000000 00000000 11101111 00000000     00000000 00000000 00000000 00110011n=  10011101 01101111 11101111 00110011

或运算的经典用途

将字节数据合并为int数据:

代码: int b1 = 0x9d; int b2 = 0x6f; int b3 = 0xef; int b4 = 0x33; int n = (b1<<24)|(b2<<16)|(b3<<8)|b4; System.out.println(Integer.toBinaryString(b1)); System.out.println(Integer.toBinaryString(b2)); System.out.println(Integer.toBinaryString(b3)); System.out.println(Integer.toBinaryString(b4)); System.out.println(Integer.toBinaryString(n));

转载于:https://www.cnblogs.com/mike-mei/p/8376088.html

你可能感兴趣的文章
asp.net C#后台实现下载文件的几种方法(全)
查看>>
Web前端开发工程师的具备条件
查看>>
为什么要用日志框架 Logback 基本使用
查看>>
实用Android开发工具和资源精选
查看>>
TileMap
查看>>
JS属性大全
查看>>
java复制文件
查看>>
第一册:lesson seventy nine.
查看>>
GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例
查看>>
团队作业
查看>>
数据持久化时的小bug
查看>>
mysql中key 、primary key 、unique key 与index区别
查看>>
bzoj2257
查看>>
Linux查看文件编码格式及文件编码转换<转>
查看>>
Leetcode: Find Leaves of Binary Tree
查看>>
Vue 模板解释
查看>>
http://www.bootcss.com/
查看>>
20145308 《网络对抗》 注入shellcode+Return-to-libc攻击 学习总结
查看>>
将多张图片和文字合成一张图片
查看>>
自己动手写ORM(01):解析表达式树生成Sql碎片
查看>>