二进制的秘密

逢2进1的计数规则(重要)

2进制

规则 : 逢2进1

数字 : 0 1

权 : 128 64 32 16 8 4 2 1

基数 : 2

10进制计数规则

10进制

规则 : 逢10进1

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

权 : 万 千 百 十 个

基数 : 10

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

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

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 00001011 = 8+2+1=11
00000000 00000000 00000000 00001100
00000000 00000000 00000000 00001101
00000000 00000000 00000000 00001110
00000000 00000000 00000000 00001111
00000000 00000000 00000000 00010000
...
00000000 00000000 00000000 00011001 = 16+8+1=25
...
00000000 00000000 00000000 01101000 = 64+32+8=104
...
package binary ;
public class Demo01 {
public static void main ( String [] args )
{
/*
* 如何查看整数的 2 进制存储情况
* - java 编译时候,将数字编译为 2 进制数
* - 运行期间变量中存储的是 2 进制数
* - 输出变量时候, Java 利用 API 方法,将 2
进制转换为 10 进制字符串
* 利用 valueOf 方法转换!
* - Integer.toBinaryString(n) 将整
n 在内存中 2 进制情况显示出来
*/
int n = 50 ; //n=110010
System . out . println ( n ); // 利用 valueOf
转换 2 进制为 10 进制字符串输出
System . out . println ( Integer . toBinaryString (
n ));
System . out . println ( Integer . toBinaryString (
104 ));
/*
* 输出 0~200 2 进制, 手工计算 20 个数的 10
进制值,编程验证
*/
for ( int i = 0 ; i < 200 ; i ++ ){
System . out . println ( Integer . toBinaryString (
i ));
  }
 }
}
什么是16进制 
逢16进1的计数规则
16进制用途 : 16进制用于缩写2进制
= 2进制书写非常繁琐
= 16进制的基数是2进制的基数4次方,2进制每4位数可以缩写为1个16进制数
package binary ;
public class Demo02 {
public static void main ( String [] args )
{
/*
* 2 进制与 16 进制
* - Java7 提供了 2 进制字面量前缀 0b
* 可以在数字中添加下划线,不影响数值
* - 2 进制直接书写非常繁琐
* - 16 进制缩写 2 进制就非常方便
* 2 进制的最低位开始, 每 4 位数缩写为 1
16 进制数 补码
计算中一种表示有符号数编码,其核心思想就是将固定
位数 2 进制分一般作为负数。
如何将固定位数 2 进制分一半作为负数?
4 2 进制数讲解如何设计补码
* - 0x 16 进制的前缀
* - 计算内部没有 10 进制,没有 16 进制,只有
2 进制!
*/
int n = 0b11_0010 ; //32+16+2=50
System . out . println ( n );
n =
0b0001_1001_1111_0001_0100_0011_1111_0101 ;
// 1 9 f 1 4 3
f 5
System . out . println ( Integer . toBinaryString (
n ));
n = 0x19f143f5 ;
System . out . println ( Integer . toBinaryString (
n ));
long l =
0b10111111111111111111111111111111111111L ;
}
}
补码 
计算机中一种表示有符号数编码,其核心思想就是将固定位数2进制分一般作为负数
如何将固定位数2进制分一半作为负数 ?
=以4位2进制数讲解如何设计补码
=计算时候保持4位不变,多余位自动溢出
=最高位称为符号位,0是正数 , 1是负数

package binary ;
    public class Demo03 {
       public static void main ( String [] args )
{
/*
* 补码
* max 最大
* value
* Integer 整数
*/
  int n = - 3 ;
    System . out . println ( Integer . toBinaryString ( n ));
int max = Integer . MAX_VALUE ; int min = Integer . MIN_VALUE ;
System . out . println ( min );
System . out . println ( Integer . toBinaryString ( max ));
System . out . println ( Integer . toBinaryString ( min ));
System . out . println ( Integer . toBinaryString ( - 1 ));
System . out . println ( Long . toBinaryString ( - 1L   ));
     }
}
手工计算负数的值 : 计算这个数比 -1 0 位置的权。
11111111111111111111111111111111 = -1
11111111111111111111111111111101 = -1-2=-3
11111111111111111111111111111001 = -1-2- 4=-7
11111111111111111111111111111000 = -1-1-2- 4=-8
11111111111111111111111101101011 = -1-4-16- 128=-149
11111111111111111111111101101100 = -1-1-2- 16-128=-148
package binary;
public class Demo04 {
public static void main(String[] args)
{
/*
* 负数的编码
* 实验: 输出 -200 0 2 进制编码(补码)
* 随机选取 20 个数,手动计算 10 进制值
* 利用 Java 程序验算计算结果。
*/
for(int i=-200; i<0; i++){
System.out.println(Integer.toBinaryString(i
));
}
}
}
long 类型负数补码
1111111111111111111111111111111111111111111
111111111111111111111 = -1
1111111111111111111111111111111111111111111
111111111111111100110 =-26
互补对称现象: -n = ~n+1 - 7 = 11111111 11111111 11111111 11111001 = - 1 - 2 - 4 =- 7
~ - 7 = 00000000 00000000 00000000 00000110 = 2 + 4 = 6
~ - 7 + 1 = 00000000 00000000 00000000 00000111 = 1 + 2 + 4 = 7
54 = 00000000 00000000 00000000 00110110 = 2 + 4 + 16 + 32 = 54
~54 = 11111111 11111111 11111111 11001001 =- 1 - 2 - 4 - 16 - 32 =- 55
~54 + 1 = 11111111 11111111 11111111 11001010 =- 1 - 1 - 4 - 16 - 32 =- 54
代 码 :
       
public class Demo05 {
public static void main ( String [] args )
{
/*
* 验证补码的互补对称现象 -n=~n+1
*/
System . out . println ( 54 );
System . out . println ( Integer . toBinaryString ( 54 ));
System . out . println ( ~54 );
System . out . println ( Integer . toBinaryString ( ~54 ));
System . out . println ( ~54 + 1 );
System . out . println ( Integer . toBinaryString ( ~54 + 1 ));
}
}
二进制运算
运算符号 :
~ 取反 
&  与
|  或运算
>>> 右移位运算
>>  数学右移位运算
<< 左移位运算
& 与 运算 
运算规则: 逻辑乘法 有0则0
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 0
运算时候将两个2进制数对其位数, 对应位置进行运算
栗子 : 
       1      7        9       d      5     d       9       e
n = 00010111 10011101 01011101 10011110
m = 00000000 00000000 00000000 11111111
8 位掩码
k = n & m 00000000 00000000 00000000 10011110
如上运算的意义 : K中存储的是n的最后8位数 , 如上运算叫掩码(mask) 运算 
m称为mask(俺码) , 一般从低位开始1的个数称为掩码的位数
 
代码 :
  
int n = 0x179d5d9e ;
int m = 0xff ;
int k = n & m ;
package binary ;
import java . util . ArrayList ;
public class Demo06 {
public static void main ( String [] args )
{
/*
* 掩码运算
*/
int n = 0x179d5d9e ;
//4 位掩码: 0xf 0b1111 15
//6 位掩码: 0x3f 0b111111 63
//8 位掩码: 0xff 0b11111111 255
int m = 0xff ; //4 6 8 16
int k = n & m ;
System . out . println ( Integer . toBinaryString ( n ));
System . out . println ( Integer . toBinaryString ( m ));
System . out . println ( Integer . toBinaryString ( k ));
>>>右移位运算
运算规则 , 将2进制数整体向右移动,低位自动溢出舍弃,高位补0
n = 01100111 11010111 10001111
01101101
m=n>>>1 001100111 11010111 10001111
0110110
k=n>>>2 0001100111 11010111 10001111
011011
g=n>>>8 00000000 01100111 11010111
10001111
b3 = (n>>>8) & 0xff;
代码 : 
int n = 0x67d78f6d ;
int m = n >>> 1 ;
int k = n >>> 2 ;
int g = n >>> 8 ;
int b3 = ( n >>> 8 ) & 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
11011101
m = 00000000 00000000 10011101
00000000
k = n | m 00000000 00000000 10011101
11011101
上述计算的意义 两位数错位合并 
代码:
int n = 0xdd ;
int m = 0x9d00 ;
int k = n | m ;
// 检查 n m k 2 进制
<< 左移位运算
2进制数字整体向左移动 高位自动溢出 低位补零
栗子 :
n = 00100000 11101111 00110101 10010000
m = n << 1 0100000 11101111 00110101 100100000
k = n << 2 100000 11101111 00110101 1001000000
g = n << 8 11101111 00110101 10010000 00000000
代码 : 
int n = 0x20ef3590 ;
int m = n << 1 ;
int k = n << 2 ;
int g = n << 8 ;
// 按照 2 进制输出 n m k g
移动运算的数学意义
栗子 : 
        
16 8 4 2 1
          1 0 1 = 5
       1 0 1 = 10     向左移动 1 *2
     1 0 1 = 20      向左移动 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,结果没有数学意义
 
                                如果仅仅将数位向右移动 , 不考虑数学意义,则使用>>>
~   >> 数学右移位:  数学向右移动,低位自动溢出, 正数高位补0,负数高位补1,
 
                                移动一次数学除以2 , 小方向取整数 ,  如果是替代数学/2,
                                使用数学右移位
栗子 , 使用负数比较运算结果 :
n = 11111111 11111111 11111111
11001100=-1-1-2-16-32=-52
m=n>>1 111111111 11111111 11111111
1100110=-1-1-8-16=-26
k=n>>2 1111111111 11111111 11111111
110011=-1-4-8=-13
g=n>>3 11111111111 11111111 11111111
11001=-1-2-4=-7
n>>>1 011111111 11111111 11111111
1100110=max-25 没有数学意义
程序: 
int n = - 52 ; //0xffffffcc;
int m = n >> 1 ;
int k = n >> 2 ;
int g = n >> 3 ;
int x = n >>> 1 ;
// 输出 n m k g x
将一个整数拆分为4个字节
栗子 
 
            b1             b2            b3             b4
n = 00010111 10011101 01011101
10011110
b1 = 00000000 00000000 00000000
00010111
b2 = 00000000 00000000 00000000
10011101
b3 = 00000000 00000000 00000000
01011101
b4 = 00000000 00000000 00000000
10011110
代码: n =-1 n=-3 n=max n=min
int n = 0x179d5d9e ;
int b1 = ( n >>> 24 ) & 0xff ;
int b2 = ( n >>> 16 ) & 0xff ;
int b3 = ( n >>> 8 ) & 0xff ;
int b4 = n & 0xff ;
// 验证:按照二进制输出 n b1 b2 b3 b4
//n=-1 时候按照 10 进制输出是啥结果?
将4个字节合并为一个整数
b1 = 00000000 00000000 00000000
00010111
b2 = 00000000 00000000 00000000
10011101
b3 = 00000000 00000000 00000000
01011101
b4 = 00000000 00000000 00000000
10011110
b1 << 24 00010111 00000000 00000000
00000000
b2 << 16 00000000 10011101 00000000
00000000
b3 << 8 00000000 00000000 01011101
00000000
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 ;
// 按照 2 进制输出 b1 b2 b3 b3 n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值