一进制概述
1)二进制:用数字0和1表示,计算机内部用二进制,运算简单,简化了计算机结构。
2)八进制:标志的开头用0表示,用0~7的数字表示。适用于12位和36位计算机系统。
3)十六进制:标志的开头用0x表示,用0~9,,A,B,C,D,E,F表示。表示表达长度短,变得更常用。
4)位权:一个数码在不同的位置所代表的值不同。
计算机常用的进制表:
二进制转换
常用进制的换算如下表:
以上关于进制和进制转换的详细可以看我转载的文章:计算机各进制之间的转换。
三进制的位运算
常用的位运算如下表:
位运算的优点:特定情况下,计算方便,速度快,支持面广。
(1)按位与(&)
计算规则:两个二进制数位如果全为1,结果才1,其余的情况均为0。也就是:0&0=0、0&1=1、1&0=1、
1&1=1。
例如:51&5即(0011 0011)&(0000 0101) = (0000 0001),因此51&5=1。
按位与运算的特殊用法:
1)清零:如果想将一个单元清零,即使其全部二进制数位都为0,只要与一个各位都为零的数值相与,结果为零。
2)取一个数中指定位:方法是找一个数,对应x要取的位,该数的对应位为1,其余位为零,此数与x进行与运算可
以得到x中的指定位。
例如:设x=(1010 1110),要求是取x的低4位(即从右端开始计数的四个二进制数位),用x&(0000 1111) = (0000
1110)即可得到。
(2)按位或(|)
计算规则:只要二进制数位有一个为1,结果就为1。也就是说:0|0=0、0|1=1、1|0=1、1|1=1。
例如:51|5 即(0011 0011) | (0000 0101) = (0011 0111) 因此51|5=55。
按位或的特殊用法:
常用来对一个数据的某些数位置为1:方法就是找到一个数,对应x要置1的位,该数的对应位为1,其余位为零,
此数与x相或可使x中的某些位置1。
例如:将x=(1010 0000)的低4位置为1,用x | (0000 1111) = (1010 1111)即可得到。
(3)异或运算(^)
计算规则:两个二进制数位相对应不同,则该位结果为1,否则为0,也就是:0^0=0、0^1=1、1^0=1、1^1=0。
例如:51^5即(0011 0011) ^ (0000 0101) = (0011 0110) 因此51^5=54。
异或运算的特殊用途:
1)使特定位翻转,找一个数,对应x要翻转的各位,该数的对应位为1,其余位为零,此数与x对应位异或即可。
例如:x=(1010 1110),使x低4位翻转,用x ^ (0000 1111) = (1010 0001)即可得到。
2)与0相异或,保留原值。
例如:x=(1010 1110),用x ^ (0000 0000) = (1010 1110)即可保证。
拓展:两个变量交换值的方法
1)借助第三个变量来实现:C=A;A=B;B=C。
2)利用加减法实现两个变量的交换:A=A+B;B=A-B;A=A-B。
3)用位异或运算来实现:A=A^B;B=A^B;A=A^B。原理:利用一个数异或本身等于0和异或运算符合交换律,也是
交换效率最高的一种方法。
(4)取反运算(~)
计算规则:对一个二进制数按位取反,即将0变1,1变0,也就是:~1=0、~0=1。
例如:(1010 0001)按位求反的结果为(0101 1110)。
(5)左移运算(<<)
计算规则:将一个运算对象的各二进制数位全部左移若干位,左边的二进制位丢弃,右边补0。
例如:2(0000 0010) << 1 = 4(0000 0100)。
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
例如:-14(其补码是1111 0010) << 2 = (左移两位后补码为1100 1000) = -56。
11(0000 1011) << 2 = (0010 1100) = 44。
例如第一个只需要该补码的原码对应的正值,然后取相反数
1)补码减1得到反码:(1100 0111)
2)反码取反得到原码(即该负数的正值):(0011 1000)
3)计算正值:(56)
4)取相反数:(-56)
(6)右移运算(>>)
计算规则:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。操作数每右移一位,相
当于该数除以2。左补0或者补1得看被移数是正还是负。
例如:4(0000 0100) >> 2 = (0000 0001) = 1。
-14(其补码是1111 0010) >> 2 = (右移两位后补码为1111 1100) = -4。
(7)无符号右移运算(>>>)
计算规则:各个位向右移指定的位数。右移后左边空出的位用零来填充,移出右边的位被丢弃。
例子:-14 >>> 2
=(其补码为11111111 11111111 11111111 11110010) >>> 2
=(无符号右移两位后补码为00111111 11111111 11111111 11111100)
=1073741820
拓展:
负数以其正值的补码形式表示。反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,
但符号位除外。
1)原码:一个正数按照绝对值大小转换成的二进制数称为原码。
例如:(00000000 00000000 00000000 00001110)是14的原码。
2)反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。
例如:(00000000 00000000 00000000 00001110)每一位取反
得(11111111 11111111 11111111 11110001)
得(11111111 11111111 11111111 11110001)
注意:(11111111 11111111 11111111 11110001)和(00000000 00000000 00000000 00001110)互为反码。
3)补码:反码加1称为补码。
例如:(11111111 11111111 11111111 11110001)+1 = (11111111 11111111 11111111 11110010)。
因此-14的二进制表示为:
-14(11111111 11111111 11111111 11110010) >>> 2 =(00111111 11111111 11111111 11001000)
四Java内置的进制转换
在java中整数默认是int类型的,int类型占4字节(4*8=32bit)。
实例代码:
public class Test{ public static void main(String[] args){ //十进制转换为其它进制 System.out.println(Integer.toBinaryString(112));//二进制 System.out.println(Integer.toHexString(112));//十六进制 System.out.println(Integer.toOctalString(112));//八进制 //其它进制转换为十进制 System.out.println(Integer.parseInt("111001",2));//二进制 System.out.println(Integer.parseInt("27",8));//十六进制 System.out.println(Integer.parseInt("A8",16));//八进制 } }
输出结果:
五Java中的进制
(1)Java中二进制用的多吗?
平时开发中"进制转换"和"位操作"用的不多,Java处理的是高层。在跨平台中用的较多,如:文件读写,数据通
信。
(2)Java中数据类型
基本数据类有以下四种:
(3)int类型转换为字节数组
8143(00000000 00000000 00011111 11001111)
=> byte[] b=[-49,31,0,0]
第一个低端字节:8143 >> 0*8 & 0xff=(11001111)=207(或有符号-49)
第二个低端字节:8143 >> 1*8 & 0xff=(00011111)=31
第三个低端字节:8143 >> 2*8 & 0xff=(00000000)=0
第四个低端字节:8143 >> 3*8 & 0xff=(00000000)=0
拓展:
1)小端法:指的是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地端。
2)大端法:指的是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地端 。
例子如下图所示:
(4)字符串转换为字节数组
String s;
byte[] bs=s.getBytes();
(5)字节数组转化为字符串
byte[] bs=new byte[int];
String s=new String(bs);
或者String s=new String(bs,encode);//encode指编码方式:gb2312,utf-8
实例1:
public class Convert{ //int转化为byte[] public static byte[] int2Bytes(int id){ byte[] arr=new byte[4]; for(int i=0;i<arr.length;i++){ arr[i]=(byte)((int)(id>>i*8)&0xff); } return arr; } //byte[]转化为int public static int bytes2Int(byte[] arr){ int result=0; for(int i=0;i<arr.length;i++){ result+=(int)((arr[i]&0xff)<<i*8); } return result; } public static void main(String[] args) throws Exception{ byte[] arr=Convert.int2Bytes(8143); System.out.println(arr[0]+","+arr[1]+","+arr[2]+","+arr[3]); System.out.println(Convert.bytes2Int(arr)); } }
运行结果:
实例2:
public class Convert{ //long转化为byte[] public static byte[] long2Bytes(int id){ byte[] arr=new byte[8]; for(int i=0;i<arr.length;i++){ arr[i]=(byte)((long)(id>>i*8)&0xff); } return arr; } //byte[]转化为long public static int bytes2Long(byte[] arr){ int result=0; for(int i=0;i<arr.length;i++){ result+=(long)((arr[i]&0xff)<<i*8); } return result; } public static void main(String[] args) throws Exception{ String describe="我是一名Java软件工程师"; byte[] barr=describe.getBytes(); System.out.println(barr[0]+","+barr[1]+","+barr[2]+","+barr[3]); String des=new String(barr); System.out.println(des); } }
运行结果: