java进制及进制转换

本文介绍java中整数的3种进制表现形式,对进制间转换方法进行了总结。

进制及进制由来 

1.  Java中,整数有3种表现形式:
     十进制:0~9,满10进1
     八进制:0~7,满8进1,用0开头表示
     十六进制:0~9,A~F,满16进1,用0x开头表示

2.  进制的由来:任何数据在计算机中都是以二进制的形式存在,一个整数在内存也是二进制的,但是使用一大串1或0组成的数值很麻烦,所以将二进制中的3位或4位用一位表示,就出现了八进制和十六进制,进制越大,表现形式越短。这个由来也是后面进制间转换的算法基础。

进制间转换

进制间的转换是很常见的,下面列出了十进制转换成二进制、八进制、十六进制的3种方法,为了完整性,后面补充其它进制转换成十进制的2种方法。

1. 普通方法   
 也就是进行循环除法,先说十进制转换成二进制,十进制转换成二进制的原理就是进行除2运算,用while循环实现:

public class Test{
	public static void main(String[] args) {
		toBin(60);
	}
	public static void toBin(int num){
		StringBuffer sb=new StringBuffer();
		while(num!=0){
			sb.append(num%2);
			num=num/2;
		}
		System.out.println(sb.reverse());
	}
}//运行结果为打印111100
类似地,十进制转换成八进制或十六进制就是循环进行除8或16运算,因除816运算很麻烦,耗费资源较多,考虑将十进制数转换成二进制数,二进制数的每34位用一个数表示即可,因位运算与(&)、或(|)、异或(^)运算实际就是将数据转换成二进制数在内存中进行运算,所以此处考虑用位运算,使用&可以达到每次读出二进制数的后3位或4位进行依次转换。
以十六进制为例,代码如下:
public class Test2{
    public static void main(String[] args) {
		toHex(60);
	}
	public static void toHex(int num){
		StringBuffer sb=new StringBuffer();
		while(num!=0){
			int temp=num&15;
			if(temp>9){
				sb.append((char)(temp-10+'a'));
			}else{
				sb.append(temp);
			}
			num=num>>>4;//无符号右移,这样程序就对负整数也是适用的
		}
		System.out.println(sb.reverse());
	}
}

2.  查表法
十进制转换成二进制、八进制、十六进制,可以用一种通用的查表法来实现。
查表法思想:当一组数据与一个数组中的元素间存在对应关系,且这种关系有数组角标规律时,可以用查表法,这样能提高效率,简化代码。

public class Test3{

	public static void main(String[] args) {
		toBin(6);
		toBin(-6);
		toBa(60);
		toBa(-60);
		toHex(60);
		toHex(-60);
	}
	//十进制——>二进制
	public static void toBin(int num){
		trans(num,1,1);
	}
	//十进制——>八进制
	public static void toBa(int num){
		trans(num,7,3);
	}
	//十进制——>十六进制
	public static void toHex(int num){
		trans(num,15,4);
	}
	public static void trans(int num,int base,int offset){
		char[] chs={'1','2','3','4','5','6','7','8',
				     '9','A','B','C','D','E','F'};
		StringBuffer sb=new StringBuffer();
		while(num!=0){
			int temp=num&base;
			sb.append(chs[temp]);
			num=num>>>offset;
		}
		System.out.println(sb.reverse());
	}
} 
另一个很容易想到的可使用查表法解决的问题是:输入一串阿拉伯数字,将其转换成汉字大写表示。代码不在这里贴了,个人觉得这也是查表法思想的一个典型例子。

3.  使用Integer类中的静态方法
Integer类是整数基本数据类型int的封闭,类中提供了现成的静态方法可以实现进制间的转换。

public class Test4 {
	public static void main(String[] args) {
		String s1=Integer.toBinaryString(60);//十进制转二进制
		String s2=Integer.toOctalString(60); //十进制转八进制
		String s3=Integer.toHexString(60);   //十进制转十六进制
		System.out.println("60的二进制表示是: "+s1);
		System.out.println("60的八进制表示是: "+s2);
		System.out.println("60的十六进制表示是 "+s3);
	}
}

上面说了十进制转成其它进制的3个方法,那其它进制怎么转换成十进制呢?可以使用Integer类的现成方法,也可以自己写一个~

Integer类中还提供了其它进制转换成十进制的方法,就是parseInt()方法:

/*
Interger类的方法: static int parseInt(String str, int base), str是待转换成十进制的字符串,base表示进制
 */
public class Test5{
	public static void main(String[] args) {
		int t1=Integer.parseInt("111100", 2);//将字符串形式的二进制数转换为十进制数
		int t2=Integer.parseInt("74", 8);    //将字符串形式的八进制数转换成十进制数
		int t3=Integer.parseInt("3c", 16);
		System.out.println("111100的十进制值是: "+t1);
		System.out.println("74的十进制值是: "+t2);
		System.out.println("3c的十进制值是: "+t3);
	}
}

其实我们可以手动写一个效果类似于parseInt()方法的,按照其它进制转成十进制的计算原理手动编写,比如十六进制0x23c转换成十进制数计算过程是:2*16^2+3*16+12=572。下面是我自己写的~:

public class Test6 {
	public static void main(String[] args) {
        System.out.println(transTen("fffffff1"));
	}
	public static int transTen(String str){
		String regex="[0-9a-f]{8}";
		if(str.matches(regex)){
			return trans(str);
		}else{
			throw new RuntimeException("输入的字符串不合法,请重新输入");
		}
	}
	
	public static int trans(String str){
		int sum=0;
		int len=str.length();
		for(int i=0;i<len;i++){
			char ch = str.charAt(i);
			if(ch>='a'&&ch<='f'){
				sum=sum+(ch-87)*(int) Math.pow(16,len-1-i);
			}else{
				sum=sum+(int)(Integer.parseInt(ch+"")*Math.pow(16, len-1-i));
			}
		}
		return sum;
	}
}//运行结果是-15

进制转换就总结到这。

负数的二进制
负数在内存的二进制表现是对应正数的二进制取反加1;反之,一个以1开头的二进制取反再加1就是对应的正数二进制表示
Int类型数据在内存中占4个字节,也就是32位,第1位是符号位,所以int型整数的最大值是2^31-1,按负数取反加1是对应正数的算法,最小值就是第1位为1,其余31位全为0的数,也就是-2^31,这样Int型整数的取值范围就是[-2^31, 2^31-1]。
Integer类中也有静态常量表示Int型整数的最大值和最小值,分别是Integer.MAX_VALUE,Integer.MIN_VALUE。

public class Test7{
	public static void main(String[] args) {
		int max=Integer.MAX_VALUE;
		int min=Integer.MIN_VALUE;
		System.out.println("int整数最大值是: "+max);//结果是2147483647
		System.out.println("int整数最小值是: "+min);//结果是-2147483648
		int a=max+1;
		System.out.println("int型整数溢出,最大值加1是:  "+a);/*结果是-2147483648*/
	}
}

注:max在计算机二进制表示中第一位为0,其余31位为1,加1后,满2进一位,直到最高位,从而变成第一位为1,其余31位为0,这个值就是min的二进制表示;计算机只会按照其内部既有的规定运算,一个int整数占32位是不会改变的,正数和负数的计算机二进制表示也是不会变的,超过int最大值时就发生溢出

类似地,byte,short,long都是有符号整数,分别占1个字节、2个字节、8个字节,对应的封装类分别为Byte,Short,Long.
 byte型整数取值范围为[-128,127],对应Byte类有静态常量Byte.MAX_VALUE,Byte.MIN_VALUE.
short型整数取值范围为[-32768,32767],对应Short类有静态常量Short.MAX_VALUE,Short.MIN_VALUE.
long型整数取值范围为[-2^63,2^63-1],对应Long类有静态常量Long.MAX_VALUE,Long.MIN_VALUE.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值