关于Java中的数据表示的一些讨论

 1. 一个类型转换的例子

    public class NarrowConversion {
public static void main(String[] args) {
int iValue=233;
//强制把一个int类型的值转换成byte类型的值
  byte bValue=(byte) iValue;
  //将输出-23
  System.out.println(bValue);
}
}

运行后的输出结果: -23

上面程序中,将一个233整型强制类型转换为byte类型,从而变成了-23,这就是典型的溢出。

现在就上面的结果进行一下分析:

首先我们来了解一知识下计算机的基础:

所有数字在计算机底层都是以2进制形式存在的 ,原码就是直接将一个10进制数转换成2进制数,但计算机是以补码的形式保存所有的整数补码的计算规则如下:正数的补码和原码完全相同,负数的补码是其反码加1;反码是对原码按位取反,除了最高位(符号位)保持不变。

现在继续,看看上面的转换问题,下面示范了转换的过程:

[java]  view plain copy
  1. //32位的int型 00000000000000000000000011101001 (十进制233) 
  2. //转换为8位的byte型11101001  


 


 上图,就是负数补码和源码转换的示意图!

2.byte类型

java中的byte是8位的有符号数,所能表示的范围是1000 0000 (-128) ~ 0111 1111 (+127)。

public class TestByte {
	public static void main(String[] args) {
		byte bval = 127;
		System.out.println(bval);	
	}
} // 输出127
如果对byte的赋值大于127,例如 对下面的表达式

byte number = 200; // 200是int型,值超过127

byte num2 = 0xe9;  //0xe9是int型,十进制233


将会的得到编译错误,因为编译器会把整数字面量当作int,so it attempts to convert that value to a byte variable. 

However, 200 doesn’t fit in the range of a byte is from -127 to 128 so that the compiler complains.


值为127的byte类型的各种输出

public class TestByte {
	public static void main(String[] args) {		

		byte bval1 =  (byte)127;
		System.out.println("(byte)127输出");
		System.out.println("10进制表示:"+ bval1);
		System.out.println("2进制表示:"+Integer.toBinaryString(bval1));		
		System.out.println("16进制表示:"+Integer.toHexString(bval1));
		System.out.println("16进制格式输出:"+String.format("%02x", bval1));
	}
}

运行结果:

10进制表示:127
2进制表示1111111		
16进制表示:7f
16进制格式输出:7f


做一点改变,将变量的值改为-4:

byte bval1 =  (byte)-4;
System.out.println("(byte)-4输出");
System.out.println("10进制表示:"+ bval1);
System.out.println("2进制表示:"+Integer.toBinaryString(bval1));		
System.out.println("16进制表示:"+Integer.toHexString(bval1));
System.out.println("16进制格式输出:"+String.format("%02x", bval1));
运行结果:

(byte)-4输出
10进制表示:-4
2进制表示:1111111111111111111111100
16进制表示:fffffffc
16进制格式输出: fc
这里bvall值为-4的时候2进制输出和16进制输出明显要比值为127时长很多,这里输出的实际上是值为-4的int型的变量的输出。

java.lang.Integer.toBinaryString() 方法的声明如下:

public static String toBinaryString(int i)
bvall会被转换为int型并赋值给i,-4的的8位二进制补码为:11111100,当转换为int时会进行符号扩展,即为1111111111111111111111100。

bvall为127时上面的过程同样发生,127的的8位二进制补码为:01111111,转为32位int型,00000000000000000000000001111111,方法

toBinaryString()在输出时把前面的0省去了。


用值为153(十六进制为0x99)int字面量给bvall赋值,再看会发生什么:

byte bval1 =  (byte)0x99;
System.out.println("(byte)结果");
System.out.println("10进制表示:"+ bval1);
System.out.println("2进制表示:"+Integer.toBinaryString(bval1));		
System.out.println("16进制表示:"+Integer.toHexString(bval1));
System.out.println("16进制格式输出:"+String.format("%02x", bval1));

结果输出:

10进制表示:-103
2进制表示:11111111111111111111111110011001		
16进制表示:ffffff99
16进制格式输出:99
要想输出153需要下面的操作:

System.out.println(bval1&0xFF);
byte型的 bval1和字面量为0xFF的int型数据进行&运算时 bval1(10011001)会被转换成int型,变为11111111111111111111111110011001,然后执行按位与


11111111 11111111 11111111 10011001 (bval1)
00000000 00000000 00000000 11111111 (0xff ) AND
--------------------------------------------------------
00000000 00000000 00000000 10011001


有了上面的讨论可以执行如下操作:

byte bval1[] = { (byte)0x77, (byte)0x88, (byte) 0x99 };
		System.out.println("bval1[]输出");
		for(int i=0; i < bval1.length ; i++){
			System.out.println("10进制表示:"+ (bval1[i] & 0xff));
			System.out.println("16进制表示"+ String.format("0x%02x", bval1[i]));
		}


3.代表一个整数的字节数组转换为16进制显示

       有一个简单的方法,即使用BigInteger
       byte bytes[] = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)127};
String result = new BigInteger(1, bytes).toString(16); 
System.out.println("result:"+ result);

不过,与java.lang.Integer.toHexString()方法类似,结果会省去前面的零,result的输出为0x7f,而不是0x0000007x。

要输出前面的零可以用这样做:

 System.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(bytes));

将会输出:000000007F


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值