Java基本數據類型及其運算
1. 整型運算
- 四則運算
對於整型類型,Java只定義了帶符號的整型,因此,最高位的bit表示符號位(0表示正數,1表示負數)。各種整型能表示的最大範圍如下:
- byte:-128 ~ 127
- short: -32768 ~ 32767
- int: -2147483648 ~ 2147483647
-
long: -9223372036854775808 ~ 9223372036854775807
因此存在溢出情況,求解溢出情況只需要將具體的數換爲二進制進行加減即可,如果最高位變爲1,則溢出之後的數又會變爲負數
注:沒有必要爲了節省內存而使用byte和short進行整數運算,範圍太小,即使確定了在byte類型內,後期的各種與int的轉換會使代碼十分冗餘,難以維護
int i = 0 while(i>0){//不是死循環,因爲會溢出變爲負數 i += 1000; }
-
移位運算
在計算機種整數總是以2進制的形式存在
//左移,包括符號位向左截斷相應的位數,而右邊用0補上 int shitNum = 15;//00000000 00000000 00000000 00001111 int shitNumLeft1 = shitNum << 1;//00000000 00000000 00000000 00011110 System.out.println(shitNumLeft1);//移位之後在轉換二進制的時候相當於多乘了一個2, 30 int shitNumLeft2 = shitNum << 2;//00000000 00000000 00000000 00111110 System.out.println(shitNumLeft2);//移位之後在轉換二進制的時候相當於多乘了兩個個2, 60 int shitNumLeft28 = shitNum << 28;//11110000 00000000 00000000 00000000 System.out.println(shitNumLeft28);//移位過多可能會造成負數 -268435456,也就是說左移運算用作乘2工具是有風險的 //左移一個負數,帶符號移位,可能會變正,但也是乘2 shitNum = -15; int shitNumNevigateLeft = shitNum << 1; System.out.println(shitNumNevigateLeft);
左移相當於乘2,符號位在截斷範圍內,可能會出現正負交替的情況,如果沒有發生有效數位的丟失那麼左移幾位就相當於乘以幾次2,如果移動的位數大於32則先對32求餘在移位餘數(移33和移1一致),並且移位之後並沒有改變原來的數,只是得到一個新數。注:觀看以上看出左移是無法用作乘2工具的
//正數右移就是除2,最後會爲0,移出的截斷,右邊0補充 int shitNum = 15;//00000000 00000000 00000000 00001111 int shitNumRight1 = shitNum >> 1;//00000000 00000000 00000000 0000111 System.out.println(shitNumRight1);//移位之後在轉換二進制的時候相當於除一個2,7 int shitNumRight2 = shitNum >> 2;//00000000 00000000 00000000 00000011 System.out.println(shitNumRight2);//移位之後在轉換二進制的時候相當於除兩個個2, 3 int shitNumRight28 = shitNum >> 28;//00000000 00000000 00000000 00000000 System.out.println(shitNumRight28);//移位過多可能會造成0 //負數右移也是除2,但是最高位不動,最後爲-1,就是 >> 對於負數來說爲不帶符號位的右移 int n = -536870912; int a = n >> 1; // 11110000 0000000 0000000 00000000 <= -268435456 int b = n >> 2; // 10111000 0000000 0000000 00000000 <= -134217728 int c = n >> 28; // 10000000 0000000 0000000 00000001 <= -2 int d = n >> 29; // 10000000 0000000 0000000 00000000 <= -1 //>>> 爲帶符號位的右移,負數一旦帶符號移位就變爲正數,但本質絕對值可能不再是除2 int n2 = -536870912; int a2 = n >>> 1; // 01110000 0000000 0000000 00000000 <= 1879048192 int b2 = n >>> 2; // 00111000 0000000 0000000 00000000 <= 939524096 int c2 = n >>> 29; // 00000000 0000000 0000000 00000111 <= 7 int d2 = n >>> 31; // 00000000 0000000 0000000 00000001 <= 1
右移相當於除2,>> 符號位不再移動範圍內,>>>符號位在移動範圍內,移動位數過多可能會爲0,並且右移運算符種的>>一定可以用作除法的工具,而且效率高。如果移動的位數大於32則先對32求餘在移位餘數(移33和移1一致),並且移位之後並沒有改變原來的數,只是得到一個新數。
-
位運算
- 與運算,兩bit同爲1爲1
- 或運算,任意一bit爲1爲1
- 非運算,01互換
-
異或運算,兩bit不同爲1,相同爲0
int i = 167776589; // 00001010 00000000 00010001 01001101 int n = 167776512; // 00001010 00000000 00010001 00000000 System.out.println(i & n); // 167776512
2.浮點數運算
浮點數運算與整數運算相比只能進行四則數值運算,不能移位運算,位運算,浮點數的表示範圍比整形還要大,但是在計算機內部浮點數無法精確的表示。也就是說浮點數的運算存在誤差,因此判斷兩個浮點數是否相等一般採用差值小於某個一個很小的數
// 比較x和y是否相等,先計算其差的絕對值:
double r = Math.abs(x - y);
// 再判斷絕對值是否足夠小:
if (r < 0.00001) {
// 可以認爲相等
} else {
// 可以認爲不相等
}
注:整數除0時會報錯,浮點數除0時返回特殊值
double d1 = 0.0 / 0; // NaN
double d2 = 1.0 / 0; // Infinity
double d3 = -1.0 / 0; // -Infinity
3.布爾運算
boolean永遠只有true和false兩種值
短路運算 && || ,值得一提的是三元運算符也是短路運算符,確定結果之後不會執行剩下的表達式
4. 字符字符串
在Java種字符和字符串是兩種不同的類型
4.1char
基本數據類型,一個char保存一個Unicode字符,可以直接將字符賦給char變量,也可以轉義字符u+Unicode編碼值賦值,將字符賦給int類型就可以看到對應的Unicode編碼。
char c = 'a';
char c = '\u0041';
int unicodeVlaue = 'a';
4.2String
引用類型變量,String具有不可變性,因爲源碼中用final 修飾了char[] ,因此二次對同一string變量賦值,其實是創建了新的字符串對象將引用直接替換了,原來的String對象將被垃圾回收機制回收。
String = "123 ";//可以包含空格
String = " 123 \"";//String 種用""標識字符串的開始結束,如果字符串本身包含",就用\",也有其他的轉義字符
String message = "輸出:";
int num = 9;
System.out.println(message + num);//+ 爲字符串拼接,可以在多個字符串之間執行,也可以用字符串與其他任何類型進行拼接,形成新的字符串
引用類型變量的值可以爲null值