DLancerC

Java Puzzler(5-6)

5. 十六进制和八进制

1
2
3
4
5
6
7
8
9
10
11
12
13
System.out.println(0x80);//128
//0x81看作是int型,最高位(第32位)为0,所以是正数
System.out.println(0x81);//129
System.out.println(0x8001);//32769
System.out.println(0x70000001);//1879048193
//字面量0x80000001为int型,最高位(第32位)为1,所以是负数
System.out.println(0x80000001);//-2147483647
//字面量0x80000001L强制转为long型,最高位(第64位)为0,所以是正数
System.out.println(0x80000001L);//2147483649
//最小int型
System.out.println(0x80000000);//-2147483648
//只要超过32位,就需要在字面常量后加L强转long,否则编译时出错
System.out.println(0x8000000000000000L);//-9223372036854775808
  • △ 如果Hex和Octal转换为10进制时字面常量的最高位为1,这个数为负数

  • 十六进制的字面常量表示的是int型,如果超过32位,则需要在后面加“L”,否则编译过不过。如果为32,则为负int正数,超过32位,则为long型,但需明确指定为long。

  • 通常最好避免混合类型运算

6. 多重转型(二进制原理)

Type Bit Length
Int 32位 2^31-1
byte 8位 2^7-1
char 16位 2^16-1

数据类型都要保留最高位作为符号位

有符号的数据类型存储是先将其无符号数Binary,在将其到最高位都置1
如:

1
2
3
4
System.out.println(Integer.toBinaryString(-1));
//1111 1111 1111 1111 1111 1111 1111 1111
System.out.println(Integer.toBinaryString(-100));
//1111 1111 1111 1111 1111 1111 1001 1100
  • 符号扩展
    进行符号扩展,即短数据类型的符号位填充到长数据类型的高字节位(即比短数据类型多出的那一部分),保证扩展后的数值大小不变

    1
    2
    3
    byte x=-1; int y=x;
    //则x的二进制值为1111 1111,y的值应为1111 1111 1111 1111 1111 1111 1000 1001;
    byte =1; short y=x; //则y的值应为0000 0000 0000 0000 0000 0000 0000 0001;
  • 零扩展
    进行零扩展,即用零来填充长数据类型的高字节位

    1
    2
    unsigned char x=1000 1001b; short y=x; //则y的值应为00000000 10001001b;
    unsigned char x=0000 1001b; short y=x; //则y的值应为00000000 00001001b;

从较窄整型转换成较宽整型规定:如果最初的数值类型是有符号的,就进行符号扩展;如果它是char,那么不管它转化成什么类型,都是进行零扩展

1
2
3
4
5
6
7
8
char c = (char)(0xff & b);
/* 0000 0000 0000 0000 0000 0000 1111 1111 (0Xff)
& 1111 1111 1111 1111 1111 1111 1001 1100 (b=-100)
-----------------------------------------
0000 0000 0000 0000 0000 0000 1001 1100 (100)
*/
//0xff是第八位全部置1;其他位全部置0;
//上面是不进行符号扩展