1、直接常量
十六进制的表示:0x或0X为前缀,后接十六进制的形式,如0x12f7
八进制d的表示:0为前缀,后接八进制的形式,如0123;
指数计数法:1.23E-2.3或者1.23e-2.3均表示1.23*10^(-2.3),这里e不表示自然科学数,而表示10
2.计算机中数的表示
在计算机的底层数都是以二进制存储的,最高位一般表示符号位,0表示正数,1表示负数,那么在计算机中是如何保存数字的呢?
a.原码表示:最高位作为符号位,剩余位数表示数值,比如用八位数据表示+7和-7
+7:00000111 -7:10000111
n位表示的数据范围:-2^(n-1)-1~0~2^(n-1)-1
问题:0有两种表示形式:+0;00000000,-0:10000000,所以不采用
b.反码表示:最高位作为符号位,正数不变,负数剩余位数用其反码表示
+7:00000111 -7:11111000
问题:0有两种表示方法:+0;00000000,-0:11111111,所以不采用
n位表示的数据范围:-2^(n-1)-1~0~2^(n-1)-1
c.补码表示:最高位作为符号位,正数剩余位数不变,负数剩余位数用其反码+1之后表示
+7:00000111 -7:11111001
n位表示的数据范围:-2^(n-1)~0~2^(n-1)-1
让我们再来看下这种情况下0的表示:+0:00000000.-0:11111111+1=000000000,产生了溢出,最高位舍去,结果与+0相同,也就是以补码表示,0只有一种表示方法,所以在计算机中采用这种编码方式。
总结:正数的原码、反码、补码相同;负数的反码为原码取反,补码为反码+1(除符号位)
3.按位操作符
按位操作符:&(与)、|(或)、^(异或)、~(非)
按位操作符用来操作整数基本类型中的单个”比特“。即二进制位,这些操作符均可与=联合使用。
int a=2;
int b=5;
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(a&b));
System.out.println(Integer.toBinaryString(a|b));
System.out.println(Integer.toBinaryString(a^b));
System.out.println(Integer.toBinaryString(~b));
output:
10
101
0
111
111
11111111111111111111111111111010
Key:将boolean值作为单个比特对待,则可对其进行与、或、、异或的操作,但不能进行非得操作,避免与逻辑运算中的非产生混淆。同时不会发生短路。(短路的介绍可以参考http://my.oschina.net/992257586/blog/338554)
boolean test1() {
System.out.println("test1 true");
return true;
}
boolean test2() {
System.out.println("test2 false");
return false;
}
boolean test3() {
System.out.println("test3 true");
return true;
}
boolean result=test1()&test2()&test3();
output:
test1 true
test2 false
test3 true
比较可以发现这儿并没有发生短路。
4.移位操作符
移位操作符:<<(左移),>>(有符号右移),>>>(无符号右移),均可与=号联合使用,表示将数据移位n位后再赋给数据。
a.<<n:将数据左移n位,右边的n位用0补全
int a = 2;
a <<= 2;
System.out.println(a);
output:8,左移2位,相当于乘4
向左移1位,相当于将数*2,并且效率比*更高,因为移位操作符是在底层直接对位进行操作的
b.>>n:将数据右移n位,若符号为正,则将左边的位数以0补齐;若符号为负,则将左边的位数以1补齐。向右移1位,相当于将数除2
int a = -16;
a >>= 2;
System.out.println(a);
output:-4,右移2位,相当于除4
c.>>>n:将数据右移n位,无论符号位为正为负,均将高位补0
int a = -16;
a >>>= 2;
System.out.println(a);
output;1073741820,因为在高位补0的原因,所以结果变成了正数。
Key:1.如果对byte,short,char类型的数值进行移位操作时,那么在移位操作前,它们会被转换成int类型,并且得到的结果也是一个int类型的值。
2.如果使用移位操作结合赋值操作时有可能得不到正确结果。
byte a=2;
a<<=23;
System.out.println(a);
output;0,将2向左移位23位,由于结果超出了byte的范围,所以发生了将高位舍去,舍去后的结果为00000000,所以结果为0.
那么,既然结果超出了byte的范围,为什么编译器没有提示我们进行强制转换呢?
这是因为对于char、byte、short,符合赋值并不需要类型转换,尽管它们进行类型提升,但也会获得与直接算术运算相同的结果。
byte a=2;
a+=2;//right
//a=a+2;error,need to cast
在编译器里,下面的语句编译器就会提示我们进行强制转换,而上面的那句则不需要,这一点需要时刻记住的。