前言
很多人学习二进制的时候都有思考和向老师钻牛角筋过文章中的几个基础问题,但是很多老师并不会或者没有时间给你详细解释和推导,这篇文章只是自我尝试的一些理解路线,希望能够给大家一点启发。
提示:以下是本篇文章正文内容,下面案例可供参考
一、原始一问:数和进制到底是什么?
数字:数字其实是人类发明的一种可量化表达的规则,当大家都遵循规则的时候,人类互相之间的量化沟通就能够实现,彼此之间也能更准确的知道对方想表达的量化内容,做到“心中有数”。 数字规则,其中首要的规则就是进制,我们通常说的数字都是要基于具体的进制,生活中没有特殊说明情况下,大家默认的都是10进制。
计数规则:从小到大,从右到左,先试图用进制内可以表示的符号去表示(如10进制是0-9共10个符号,二进制是0和1两个符号),当进制内符号不能表达的时候,增加数字的位数,比如一位10进制最多只能表达到9,超过9就需要增加位数。
取值范围:
二进制:1=1;2=10;3=11;4=100;5=101;6=110;7=111;所以byte基本类型需要1个字节共8位二进制,最大表示数为2的8次方减去1,但是因为有一位需要作为符号位,所以最大表示数为2的7次方-1;
十进制:9=9;10=10;11=11;19=19;99=99;100=100;所以最大三位数为999,即10的3次方-1;
二、java基本类型int为什么负数的绝对值比正数大?
因为0放在了正数来表示,0用二进制表示为0...0,32个0;所以-2^31二进制表示为10000000...
三、为什么负数为二进制数按位取反再加1(即补码)?
为了位运算的同一规则和运算效率。所有的运算其实最后都是转换为二进制的位运算,如取反~,左移《,右移》,无符号右移>>>,按位与&,按位或|,按位异或^(相同为0不同为1) 。所以负数定为取反+1是为了所有的加减乘除都能够适用于一套二进制运算规则,而无需考虑是正数相加,还是负数相加,又或者是正数加负数,无需设计三条分支,能够适用于同一套位运算规则,增加运算速度,例如取相反数,无论正负数取相反数的时候二进制位的运算规则都是按位取反再加1,即:-x=~x+1,推导公式见下方例子推导。
带符号右移>>:右移后,左边用符号位补齐;
不带符号右移>>>:右移后,左边用0补齐;
相反数的二进制表达:-x=~x+1,注意,最小负数的相反数是它自己,0取反后也是它自己
例子推导:
1=0000...1 —》11111...0+1=111...1=-(0000...0+1)=-000...1=-1;
公式推导:
1)假设x是正数,二进制记做:0a,那么0a按位取反得到1b,a和b都是31位二进制且互反;
2)因为1b第一位是1,即是负数,根据负数的定义1b=-(0a+1)=-0a-1;
3)因为0a=x,所以x按位取反=~x=1b=-(0a+1)=-0a-1=-x-1;
4)所以-x=~x+1;
5)假设x是负数1a,证明-1a=0b+1。因为1a=-(0b+1)=-0b-1,所以-1a=0b+1;
总结
学习编程就是学习人定的各种规则,既然你不是制定规则的那个人,那你就得遵守已被所有人认可的规则,也就是规范。