二进制通俗讲解

二进制在编程中的地位举足轻重,这个名词听上去高深莫测,下面来揭开它神秘的面纱。

  我们平时计数都是以10为进制,我们平时数数:1、2、3、4、5、6、7、8、9,数到10时导致个位变成0,十位变成了1,因为9+1要向十位进一,十进制意味着数字的每一位最小为0,最大为9。同理,二进制意味着数字的每一位最小为0,最大为1,十进制的2在二进制如何表示呢?1+1意味着要进一位,对于二进制来说,1+1=10,注意!这里的10不是十进制的十。二进制的减法原理和十进制的减法一样,10-1=1,因为0减1,必须借一位才能够完成这个运算。
  二进制里有个位、十位的概念吗?没有。
  在解释这个问题前先介绍几个公式,计算机内有一些相应的单位去计量容量,这些单位跟程序员相关的的主要有:
  1字节=8位
  1字=16位
  双字=32位=2字
  如何称呼二进制中的位呢?比如10001100是一个总共有8位的数,也称为一个字节,10001100这个字节最左边的1称为字节的最高位,最右边的0称为字节的最低位。从最高位向最低位的方向到第几位就称为高几位,如1000称为这个字节的高4位,100称为这个字节的高3位;从最低位向最高位的方向数起到第几位就称为低几位,如:1100称为这个字节的低4位,100称为这个字节的低3位。
字节从最低位往最高位的方向依次称为第0位(注意不是第1位)、第1位、第2位直到第7位(注意不是第8位),10001100的第0位是0,第2位是1,第3位是1,这个称呼对于一个字、一个双字以及更大的计量单位都是一样的。

 

  下面我们把二进制10001100转化为十进制,以加深大家对二进制的认识:(^表示乘幂,2^3表示3个2相乘,2^4表示4个2相乘,以些类推,2^n表示n个2相乘;*表示乘号;n^m的意义亦可视为1×n×n×n...︰起始值1(乘法的单位元)乘底m这么多次。除了0之外所有数的零次方都是1,即n^0=1;幂的指数是负数时,等于1/n^m。)
  计算过程很简单:1*(2^7)+0*(2^6)+0*(2^5)+0*(2^4)+1*(2^3)+1*(2^2)+)+0*(2^1))+0*(2^0)=128+0+0+0+8+4+0+0=140。
  这个公式为什么能把二进制计算成十进制呢,先看看十进制是如何成为人们心目中的数字的。
  1206=1*(10^3)+2*(10^2)+0*(10^1)+6*(10^0)     
     =1000+200+0+6=1206
   这个相信大家都能理解,因为十进制是以10为进制的,所以十位是多少就表示这个数中含多少个10,百位是多少表示这个数中含多少个100.比如一个十进制有3位,那么该数=百位*(10^2)+十位*(10^1)+个位*(10^0);如果一个十进制有n位,那么该数=第n-1位值*(10^(n-1))+第n-2位值*(10^(n-2))+......+第1位值*(10^1)+第0位值*(10^0)。
  因为二进制是以2为进制的,理所当然,所以对于一个n位的二进制来说,转化成十进制的方式是:第n-1位值*(2^(n-1))+第n-2位值*(2^(n-2))+......+第1位值*(2^1)+第0位值*(2^0)。
  通常我们在编程时使用十六进制来表示二进制,而不直接使用二进制,十六进制数的10-15如何表示呢?它们分别表示为A、B、C、D、E、F。在C语言中,可以使用0X,后跟十六进制的方式来描述一个二进制数,比如0x02表示二进制中的10,二进制如何转换成十六进制呢?

 

  比较实用的方法是将二进制以4位为一组,每4位转化为一个十六进制数字。
  以10001100为例,将它分为高4位1000和低4位1100,分别按照按照前面所说的方法转化成十进制,高4位1000:1*2^3=8;低4位1100转化成十进制:1*2^3+1*2^2=12。
  8表示为十六进制仍然是8,而12表示为十六进制是C,所以10001100用十六进制表示是8C,C语言描述是0X8C。
============================================== 
小技巧集锦:
  1、可以先把一个8位的二进制数11111111事先转化十进制数,并记住,下次转化时非常方便,第7位转化为10进制是128,第6位转化后是64,第5位转化后是32,第4位转化后是16,第3位转化后是8,第2位转化后是4,第1位转化后是2,第0位转化后是1,转化时把所有值为1的位的转化后十进制数相加即可。二进制1100转化成十进的过程:8+4=12

 

二进制图文详解 二进制Binary 2进制 逢二进一的计数规则。 在计机内部,一切数据都是2进制的!! 2进制的数字 补码 补码本质是一种解决负数问题的法。 1. 将数据的一半当做负数使用。 2. 补码在内存中是2进制的,显示的时候为10进制。 - Java利用法支持了补码计- Integer.parseInt() - Integer.toString() 3. 补码的缺点: - 不支持超范围计 - 超范围计自动溢出 4. 解决补码的缺点:采用更大范围(更多位数)的补码 Java是如何计 -2-1 的 补码的规律 1. 最大值的规律:最高位0 剩下全是1 - int类型:一个0,311 - long类型:一个0,63个1 2. 最小值的规律:最高位1 剩下全是0 - int类型:一个1,31个0 - long类型:一个1,63个0 3. 负数的最高位是1, 正数最高位是0 - 最高位做为识别正数和负数的标志位:称为符号位 - 注意:符号位不是用来表示正负号的!!! 4. -1 的规律:所有位都是1!! 5. 溢出是有规律的! 是一个周期性计结果。 - 最大值+1 = 最小值 6. 补码的对称现象:-n = ~n + 1 案例: int max = Integer.MAX_VALUE; System.out.println(Integer.toBinaryString(max)); int min = Integer.MIN_VALUE; System.out.println(Integer.toBinaryString(min)); long lmax = Long.MAX_VALUE; System.out.println(Long.toBinaryString(lmax)); long lmin = Long.MIN_VALUE; System.out.println(Long.toBinaryString(lmin)); //-1的规律 int n = -1; System.out.println(Integer.toBinaryString(n)); long l = -1L; System.out.println(Long.toBinaryString(l)); //最大值+1溢出得到最小值 // 推论:Java中的int数字是按照补码圆环排列的 int m = Integer.MAX_VALUE+1; System.out.println(m);//最小值 //一个数的溢出测试: n = 345; m = n + Integer.MAX_VALUE+1; System.out.println(m);//负数 m = n + Integer.MAX_VALUE+1+ Integer.MAX_VALUE; System.out.println(m);//344 正数 m = n - (Integer.MAX_VALUE+1+ Integer.MAX_VALUE+1); System.out.println(m);//345 正数 经典面试题1 正数的溢出结果是负数(错误!!!) 经典面试题2 int i = Integer.MAX_VALUE+1; System.out.println( Integer.toBinaryString(i)); 选择运行结果(D): A. 11111111111111111111111111111111 B. 1111111111111111111111111111111 C. 01111111111111111111111111111111 D. 10000000000000000000000000000000 经典面试题3 System.out.println(~-55); 如上代码的运结果: ( 54 ) System.out.println(~-230); 如上代码的运结果: ( 229 ) System.out.println(~55); 如上代码的运结果: ( -56 ) 16进制 16进制是2进制的简写形式 2进制运 1. ~ 取反运 2. & 与运(逻辑乘法) 运规则: 1 & 1 = 1 1 & 0 = 0 0 & 1 = 0 0 & 0 = 0 与运用途: n: 00010100 11010111 01010001 11101010 m: 00000000 00000000 00000000 11111111 n&m-------------------------------------- k 00000000 00000000 00000000 11101010 如上的与运是一个有意义的运: 意义在于k是数字n的低8位数字!!m是一个分割模板,称为Mask(面具) 案例: int n = 0x14d751ea;//16简写(缩写)的2进制 int m = 0xff;//255 int k = n&m; //输出 n m k 的2进制 3. | 或运(逻辑加法) 规则: 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1 用途: n = 00000000 00000000 00000000 10110101 m = 00000000 00000000 11011011 00000000 n|m ------------------------------------ k 00000000 00000000 11011011 10110101 //判断是否读取到文件的末尾: ch1 00000000 00000000 00000000 10110101 ch2 00000000 00000000 00000000 11001111 ch3 11111111 11111111 11111111 11111111 ch4 11111111 11111111 11111111 11111111 ch1|ch2|ch3|ch4 ------------------------- -1 11111111 11111111 11111111 11111111 if(ch1|ch2|ch3|ch4 >> 逻辑右移动运 将2进制数的每个位向右移动,左侧空白补充0 规则: n: 00010100 11010111 01010001 11101010 m = n>>>1; m: 000010100 11010111 01010001 1110101 m = n>>>8; m: 00000000 00010100 11010111 01010001 案例: int n = 0x14d751ea; int m = n>>>1; //按照2进制输出n 和 m m = n>>>8; //按照2进制输出 m k = (n>>>8)&0xff; //按照2进制输出 k > 思考:将一个int拆分为4个8位数 d1 d2 d3 d4? 5. >> 数学右移位运 复习:移动小数点计 一个整数 312331. 将小数点先左移动一次 31233.1 原始数据除以10 将小数点先左移动2次 3123.31 原始数据除以100 如果看做小数点不动,数字向右移动一次,原始数据除以10 ... 2进制数有同样现象:数字向右移动一次,原数据除以2 n = 00000000 00000000 00000000 01010000 m = n>>3; m = 00000000000 00000000 00000000 01010 案例: n = 80;// 0x50 m = n>>3;// n<>` 数学右移位,高位补充规则 - 正数补0 负数补1,结果满足数学规则 - 如果溢出,向小方向取整 2. `>>>` 是逻辑右移位:高位只补充0 提示:如果数学计 使用 `>>` 6. << 左移位运 将2进制数位每位向左移动,右侧填充0 拼接int d1 = 00000000 00000000 00000000 11101010 d2 = 00000000 00000000 00000000 01010001 d3 = 00000000 00000000 00000000 11010111 d4 = 00000000 00000000 00000000 00010100 d4<<24 00010100 00000000 00000000 00000000 d3<<16 00000000 11010111 00000000 00000000 d2<> 数学右移位 面试题目: 如何优化 n*8 ? 答案: n<<3 提示: 被乘数一定是 2 的n次幂 如何优化 n%8 ? 答案: n&(8-1) 如何优化 n%4 ? 答案: n&(4-1) 如何优化 n ? 答案: n&(16-1) n%0xf 提示: 除数一定是 2 的n次幂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值