进制之间的转换
进制之间转换需要区分正整数和负数,平常的面试当中,还没有遇到相关的问题,笔试阶段可能碰到一两个,我在这里做一个简单的整理,解决普通的问题应该绰绰有余。
目录
最后一位数是2的零次方,依次类推进行加法运算
例如:11100转十进制
二进制转换为十六进制的方法是,取四合一法,即从二进制的小数点为分界线,向左(向右)每四位取成一位,如 0 0 1 1| 1 1 0 1 ,左半边=2+1=3 右半边=8+4+1=13=D,结果,00111101就可以换算成十六进制的3D。
十进制转换为二进制采用“除2取余,逆序排列”法
类似十进制转二进制,不过是用16来除,如下
65036 除 16,余数12(C),商4064
4064 除 16,余数0(0),商254
254 除 16,余数 14(E),商15
15除16,余数 15(F),商0,结束
得16进制为 FE0C
十六进制转二进制方法就是一分四,即一个十六进制数分为四个二进制数
如0x1ED转换为二进制,1即为0001,E为1110,D为1101,转为二进制:111101101
类似二进制转十进制
例:2AF5换算成10进制:
用竖式计算:
第0位: 5 * 16^0 = 5
第1位: F * 16^1 = 240
第2位: A * 16^2= 2560
第3位: 2 * 16^3 = 8192
相加为10997
十进制的小数转换为二进制采用“乘2取整,顺序排列”法,具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到==所要求的精度==为止。然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。
如:0.625=(0.101)B
0.625*2=1.25==取出整数部分1
0.25*2=0.5====取出整数部分0
0.5*2=1==取出整数部分1
再如:0.7=(0.1 0110 0110...)B
0.7*2=1.4====取出整数部分1
0.4*2=0.8====取出整数部分0
0.8*2=1.6====取出整数部分1
0.6*2=1.2====取出整数部分1
0.2*2=0.4====取出整数部分0
0.4*2=0.8====取出整数部分0
0.8*2=1.6====取出整数部分1
0.6*2=1.2====取出整数部分1
0.2*2=0.4====取出整数部分0
二进制转十进制则是小数点前同正整数运算,小数点后则是从左往右乘以二的相应负次方并递减
同整数一分四和四合一方法。
与二进制转换类似
需要了解几个知识点,源码, 反码,补码
原码 :一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码
比如 00000000 00000000 00000000 00000101 是 5的 原码;10000000 00000000 00000000 00000101 是 -5的 原码。(注意,一个int类型是4字节,每个字节有8位。)
反码 :正数的反码与原码相同, 负数的反码为对该数的原码除符号位外各位取反 。
补码 :正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
比如:10000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。 那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
总结:对于正数,原码=反码=补码。对于负数而言,补码=反码+1,最高位为符号为始终不变
注意:负数使用补码转换为十六进制,-5的补码为1111 1111 1111 1111 1111 11111111 1011,转换成十六进制为0xFFFFFFFB
注意:所有参与运算的都是以补码形式进行的,结果也是补码,因此也需要将补码转换成为原码的形式存在(因为对于正数而言,原码=补码,所以我们在进行为运算的时候基本会忽略这条规则)
关于|操作,与||不同的一点是,||是断路运算
记住这个表
1.清零(&)
与操作 & ,想要哪几位清零,就和那几位为0的二进制数相与
比如 a&0结果为0
2.取一个数的指定位置(&)
比如取数 X=1010 1110 的低4位,令Y的低四位为1,其余位为0,即Y=0000 1111,进行相与操作,X&Y=0000 1110的到低四位
3.判断奇偶(&)
只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a是不是偶数。
4.将某些位置设置为1
比如将数 X=1010 1110 的低4位设置为1,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位或运算(X|Y=1010 1111)即可得到。
5.翻转指定位置(^)
比如将数 X=1010 1110 的低4位进行翻转,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行异或运算(X^Y=1010 0001)即可得到
与0^值不变
6.交换两个数(^)
通常我们交换两个值都是借助第三个变量来实现的,如:tmp=A;A=B;B=tmp.我们还可以通过位异或运算来实现,原理是:利用一个数异或本身等于0和异或运算符交换律.
如:A=A B;B=A B;A=A^B
7.使一个数的最低位为0(~)
使a的最低位为0,可以表示为:a & 1。 1的值为 1111 1111 1111 1110,再按"与"运算,最低位一定为0
8.乘以2或者除以2(<< >>)
在java中常用,见于ArrayList的扩容,也说明了Arraylist的扩容为什么是1.5,因为位移操作比普通的数学运算更快。
当位移大于32时,我们用32对其取余,即为移动的位数.每向左移动一位,相当于 2(很好理解,原来的2的n次方相加向左移位后值变成了2的n+1次方相加了),左移32位相当一没有移动*
位移分为逻辑位移和算数位移,左移都是逻辑位移,右移分为逻辑右移和算数右移。Java算数运算中,右移符号位不变,需要在高位补1。 -2^31,原码是10000000 00000000 00000000 00000000,反码是1111111 11111111 11111111 11111111,补码为反码加一为10000000 00000000 00000000 00000000,进行左移变为0.