符号扩展:当用更多的内存存储某一个有符号数时,由于符号位位于该数的第一位,扩展之后,符号位仍然需要位于第一位,所以,当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0.
比如一个用一个8位二进制表示-1,则是10000001
如果把这个书用16位二进制表示时,则为11111111 10000001 高位全都是1,这个叫做符号扩展,主要用于对其操作数。
零扩展就是全补零。不论其符号位是多少,高8位全都补0.
在Java中负数是这样表示的:
int型变量 -1 在java中是这样的:
System.out.printf("%x", -1);
//运行结果
ffffffff
而
System.out.printf("%x", 1);
//运行结果:
1
而:
System.out.printf("%x", -2);
//运行结果:
fffffffe
结论:正整数的补码与原码相同。求负整数的补码,符号位不变,数值位各位取反,最后整个数加1。
char无论转换成什么类型都执行零扩展。
较窄整型转成较宽整形的时候执行符号扩展。对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0.
system.out.println((int)(char)(byte)-1);
//运行结果:
65535
解题思路:1. int型的-1在内存中的表示为:0xffffffff
2. 转成byte型,将低8位保留变成: 0xff
3. 转成char型,窄向宽转,因为byte是有符号数则执行符号扩展变成: 0xffff
4. 转成int型,因为是char型转的所以执行零扩展变成: 0x0000ffff
5. 输出结果:65535
再看个例子:
system.out.println(Long.toHexString(0x100000000L + 0xcafebabe));
//运行结果:
cafebabe
解题思路:
1. 这是一个混合运算,是long型数和int型数的加法操作
2. 首先将0xcafebabe转成long型数字,由于该数字的符号位(最高位)被置位了,所以它是一个负数。
3. int型数转long型数是从窄到宽的转化,执行符号扩展,由于是负数,变成:0xffffffffcafebabe。
4. 执行加法操作:0xffffffffcafebabe + ox100000000=0x00000000cafebabe。
5. 输出结果:cafebabe。