1. 程式人生 > >Java Basic系列之(一):整數Integer

Java Basic系列之(一):整數Integer

Java中的數值位數
Primitive Data Types原生資料型別(共8種)
型別 位數 最小值 最大值
byte 8-bit -128=-27 127=27-1
short 16-bit -32768 32767
int 32-bit -231 231-1
long 64-bit -263 263-1
float 32-bit
double 64-bit
boolean 1-bit true和false
char 16-bit \u0000(or 0) \uffff (or 65,535 inclusive)
原生型別的預設值Default Values
Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char ‘\u0000’
String (or any object) null
boolean false
以Integer為例解釋Integer的二進位制表示法

最小值為0x80000000,最大值為0x7fffffff,因為最高位是符號位。
int型為4位元組。在計算機內部數值的二進位制表示,有正碼、反碼和補碼。一般採用二進位制補碼進行表示和運算,MIN_VALUE = 0x80000000MAX_VALUE = 0x7fffffff 就是補碼錶示的Integer的最小值(-2^31)和最大值(2^31-1)。
一個 Integer 型別佔 4 位元組,一個位元組佔 8 位二進位制碼,因此一個 Integer 總共佔 32 位二進位制碼。去除第一位的符號位,剩下 31 位來表示數值。

  • 當原碼為正數的時候,正數的原碼、反碼、補碼都相同。
  • 當原碼為負數的時候,反碼為去除符號位按位取反,補碼為去除符號位按位取反再加1。
原碼:10000000000000000000000000000001 -1 
反碼:11111111111111111111111111111110 
補碼:11111111111111111111111111111111

原碼:10000000000000000000000000000010 -2 
反碼:11111111111111111111111111111101 
補碼:11111111111111111111111111111110

原碼:11111111111111111111111111111111 -(2^31 - 1)= -2^31 + 1 
反碼:10000000000000000000000000000000 
補碼:10000000000000000000000000000001

原碼:10000000000000000000000000000000 -0 約定為 -2^31 
反碼:11111111111111111111111111111111 
補碼:10000000000000000000000000000000
如何證明最高位為符號位
for (int i = Integer.MIN_VALUE; i < 0; i++) {
    assertEquals(1, i >>> 31);
}
for (int i = 0; i < Integer.MAX_VALUE ; i++) {
    assertEquals(0, i >>> 31);
}
// << Signed left shift,
// >> Signed right shift,
// >>> Unsigned right shift, 沒有<<<這個符號.
int target = 1;
for (int i = 0; i < 31; i++) {
    assertTrue( 1 << target > 0);
}
//0_000000...0000_0
//0_000000...0000_1
//0_000000...0001_0
//0_000000...0010_0
//0_000000...0100_0
//0_000000...1000_0
十六進位制表示數值的時候,預設是int。
assertEquals((short) 0x8000, Short.MIN_VALUE);
十六進位制數表示數值的時候的特例
assertTrue(-0x8000_0000 < 0);
assertEquals(0x1, 1);
assertEquals(-0x1, -1);
關於數值的溢位問題

最大值加1或者最小值減1後會溢位。兩個符號相同的數相加才可能溢位。
為了防止溢位可以使用Math.addExact()方法。

assertEquals(Integer.MAX_VALUE + 1000, Integer.MIN_VALUE + 999);
assertEquals(Integer.MAX_VALUE + 1, Integer.MIN_VALUE);
assertEquals(Integer.MIN_VALUE + 1, 0x8000_0001);
assertEquals(-1, 0xffff_ffff);
assertEquals(0x0000_0000, 0xffff_ffff + 1);
assertEquals(0x8000_0000 + 0xffff_ffff, 0x7fff_ffff);
  • intshort的時候高位直接被捨棄,沒有符號位。
  • 16進製表示法0x1234_5678中間的下劃線無意義,便於閱讀。官方文件的說明