java负数右移_收入囊中篇---Java程序基础(二)
前言:
本篇是接著上一篇更新的,如果沒有閱讀上一篇的話,可以查閱或回顧一下。
1、收入囊中篇---Java基礎(chǔ)必備知識(一)
2、收入囊中篇---Java程序基礎(chǔ)(二)
Java程序基礎(chǔ)目錄
1、Java的基本結(jié)構(gòu)
2、變量和數(shù)據(jù)結(jié)構(gòu)
- 變量
- 基本數(shù)據(jù)類型
- 整型
- 浮點型
- 布爾類型
- 字符類型
- 常量
- var關(guān)鍵字
- 變量的作用范圍
- 小結(jié)
3、整數(shù)運算(本篇內(nèi)容)
- 溢出
- 簡潔的運算符
- 自增/自減
- 移位運算
- 位運算
- 運算優(yōu)先級
- 類型自動提升與強制轉(zhuǎn)型
- 小結(jié)
4、浮點數(shù)運算(本篇內(nèi)容)
- 類型提升
- 溢出
- 強制轉(zhuǎn)型
- 練習(xí):
- 小結(jié)
5、布爾運算
- ```
- 短路運算
- 三元運算符
- 練習(xí):
- 小結(jié) ```
6、字符和字符串
- ```
- 字符類型
- 字符串類型
- 字符串連接
- 多行字符串
- 不可變特性
- 空值null
- 練習(xí):
- 小結(jié) ```
7、數(shù)組類型
- ```
- 字符串?dāng)?shù)組
- 小結(jié) ```
3、整數(shù)運算
Java的整數(shù)運算遵循四則運算規(guī)則,可以使用任意嵌套的小括號。四則運算規(guī)則和初等數(shù)學(xué)一致。例如:
//四則運算
public class Main {public static void main(String[] args) {int i = (100 + 200) * (99 - 88); // 3300int n = 7 * (5 + (i - 9)); // 23072System.out.println(i);System.out.println(n);}
}//從左往右先乘除,后加減依次進(jìn)行- 整數(shù)的數(shù)值表示不但是精確的,而且整數(shù)運算永遠(yuǎn)是精確的,即使是除法也是精確的,因為兩個整數(shù)相除只能得到結(jié)果的整數(shù)部分:
int x = 12345 / 67; // 184 ,整型只能夠得到整數(shù)- 求余運算使用
%:
int y = 12345 % 67; // 12345÷67的余數(shù)是17特別注意:整數(shù)的除法對于除數(shù)為0時運行時將報錯,但編譯不會報錯。
溢出
要特別注意,整數(shù)由于存在范圍限制,如果計算結(jié)果超出了范圍,就會產(chǎn)生溢出,而溢出不會出錯,卻會得到一個奇怪的結(jié)果:
//運算溢出
public class Main {public static void main(String[] args) {int x = 2147483640;int y = 15;int sum = x + y;System.out.println(sum); // -2147483641 ,正數(shù)相加竟然成為了負(fù)數(shù)}
}要解釋上述結(jié)果,我們把整數(shù)2147483640和15換成二進(jìn)制做加法:
由于最高位計算結(jié)果為1,因此,加法結(jié)果變成了一個負(fù)數(shù)。
要解決上面的問題,可以把int換成long類型,由于long可表示的整型范圍更大,所以結(jié)果就不會溢出:
//運算正常
public class Main {public static void main(String[] args) {long x = 2147483640;long y = 15;long sum = x + y;System.out.println(sum); // 2147483655}
}簡潔的運算符
有一種簡寫的運算符,即+=,-=,*=,/=,它們的使用方法如下:
n += 100; // 3409, 相當(dāng)于 n = n + 100;
n -= 100; // 3309, 相當(dāng)于 n = n - 100;自增/自減
Java還提供了++運算和--運算,它們可以對一個整數(shù)進(jìn)行加1和減1的操作:
// 自增/自減運算
public class Main {public static void main(String[] args) {int n = 3300;n++; // 3301, 相當(dāng)于 n = n + 1;n--; // 3300, 相當(dāng)于 n = n - 1;int y = 100 + (++n); // 不要這么寫System.out.println(y);}
}注意++寫在前面和后面計算結(jié)果是不同的,++n表示先加1再引用n,n++表示先引用n再加1。不建議把++運算混入到常規(guī)運算中,容易自己把自己搞懵了。
移位運算
在計算機(jī)中,整數(shù)總是以二進(jìn)制的形式表示。例如,int類型的整數(shù)7使用4字節(jié)表示的二進(jìn)制如下:
00000000 0000000 0000000 00000111可以對整數(shù)進(jìn)行移位運算。對整數(shù)7左移1位將得到整數(shù)14,左移兩位將得到整數(shù)28:
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912左移29位時,由于最高位變成1,因此結(jié)果變成了負(fù)數(shù)。類似的,對整數(shù)28進(jìn)行右移,結(jié)果如下:
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1; // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2; // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3; // 00000000 00000000 00000000 00000000 = 0如果對一個負(fù)數(shù)進(jìn)行右移,最高位的1不動,結(jié)果仍然是一個負(fù)數(shù):
int n = -536870912; //11100000 00000000 00000000 00000000
int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2; // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1對比了兩種的移位運算之后,我客觀總結(jié)一下>>(右移)使用1來填補,<<(左移)使用0來填補。
如果從數(shù)學(xué)原理來理解的話就是,左移是滿2進(jìn)1,原位補0。右移是減1退位,原位補1。
還有一種不帶符號的右移運算,使用>>>,它的特點是符號位跟著動,因此,對一個負(fù)數(shù)進(jìn)行>>>右移,它會變成正數(shù),原因是最高位的1變成了0:
int n = -536870912;// 11100000 00000000 00000000 00000000
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1對byte和short類型進(jìn)行移位時,會首先轉(zhuǎn)換為int再進(jìn)行位移。
仔細(xì)觀察可發(fā)現(xiàn),左移實際上就是不斷地×2,右移實際上就是不斷地÷2。
位運算
位運算是按位進(jìn)行與、或、非和異或的運算。
- 與運算的規(guī)則是,必須兩個數(shù)同時為
1,結(jié)果才為1:
n = 0 & 0; // 0
n = 0 & 1; // 0
n = 1 & 0; // 0
n = 1 & 1; // 1- 或運算的規(guī)則是,只要任意一個為
1,結(jié)果就為1:
n = 0 | 0; // 0
n = 0 | 1; // 1
n = 1 | 0; // 1
n = 1 | 1; // 1- 非運算的規(guī)則是,
0和1互換:
n = ~0; // 1
n = ~1; // 0- 異或運算的規(guī)則是,如果兩個數(shù)不同,結(jié)果為
1,否則為0:
n = 0 ^ 0; // 0
n = 0 ^ 1; // 1
n = 1 ^ 0; // 1
n = 1 ^ 1; // 0對兩個整數(shù)進(jìn)行位運算,實際上就是按位對齊,然后依次對每一位進(jìn)行運算。例如:
public class Main {public static void main(String[] args) {int i = 167776589; // 00001010 00000000 00010001 01001101int n = 167776512; // 00001010 00000000 00010001 00000000// i&n = 00001010 00000000 00010001 00000000 = 167776512System.out.println(i & n); // 167776512}
}上述按位與運算實際上可以看作兩個整數(shù)表示的IP地址10.0.17.77和10.0.17.0,通過與運算,可以快速判斷一個IP是否在給定的網(wǎng)段內(nèi)。
運算優(yōu)先級
在Java的計算表達(dá)式中,運算優(yōu)先級從高到低依次是:
()!~++--*/%+-<<>>>>>&|+=-=*=/=
記不住也沒關(guān)系,只需要加括號就可以保證運算的優(yōu)先級正確。
類型自動提升與強制轉(zhuǎn)型
在運算過程中,如果參與運算的兩個數(shù)類型不一致,那么計算結(jié)果為較大類型的整型。例如,short和int計算,結(jié)果總是int,原因是short首先自動被轉(zhuǎn)型為int:
// 類型自動提升與強制轉(zhuǎn)型
public class Main {public static void main(String[] args) {short s = 1234;int i = 123456;int x = s + i; // s自動轉(zhuǎn)型為intshort y = s + i; // 編譯錯誤! 因為int型一般情況下是不可以轉(zhuǎn)化成為short類型的}
}但是也還是可以將結(jié)果強制轉(zhuǎn)型,即將大范圍的整數(shù)轉(zhuǎn)型為小范圍的整數(shù)。強制轉(zhuǎn)型使用(類型),例如,將int強制轉(zhuǎn)型為short:
int i = 12345; //12345為int型
short s = (short) i; // 12345為short型要注意,超出范圍的強制轉(zhuǎn)型會得到錯誤的結(jié)果,原因是轉(zhuǎn)型時,int的兩個高位字節(jié)直接被扔掉,僅保留了低位的兩個字節(jié)。
例如:7(int)=0111(int) <------> 7(short)= 11(short)
//強制轉(zhuǎn)換類型
public class Main {public static void main(String[] args) {int i1 = 1234567;short s1 = (short) i1; // -10617System.out.println(s1);int i2 = 12345678;short s2 = (short) i2; // 24910System.out.println(s2);}
}因此,強制轉(zhuǎn)型的結(jié)果很可能是錯的。
小結(jié)
整數(shù)運算的結(jié)果永遠(yuǎn)是精確的;
運算結(jié)果會自動提升;
可以強制轉(zhuǎn)型,但超出范圍的強制轉(zhuǎn)型會得到錯誤的結(jié)果;
應(yīng)該選擇合適范圍的整型(int或long),沒有必要為了節(jié)省內(nèi)存而使用byte和short進(jìn)行整數(shù)運算。
4、浮點數(shù)運算
浮點數(shù)運算和整數(shù)運算相比,只能進(jìn)行加減乘除這些數(shù)值計算,不能做位運算和移位運算。
在計算機(jī)中,浮點數(shù)雖然表示的范圍大,但是,浮點數(shù)有個非常重要的特點,就是浮點數(shù)常常無法精確表示。
舉個栗子:
浮點數(shù)0.1在計算機(jī)中就無法精確表示,因為十進(jìn)制的0.1換算成二進(jìn)制是一個無限循環(huán)小數(shù),很顯然,無論使用float還是double,都只能存儲一個0.1的近似值。但是,0.5這個浮點數(shù)又可以精確地表示。
因為浮點數(shù)常常無法精確表示,因此,浮點數(shù)運算會產(chǎn)生誤差:
//浮點數(shù)運算誤差
public class Main {public static void main(String[] args) {double x = 1.0 / 10;double y = 1 - 9.0 / 10;// 觀察x和y是否相等:System.out.println(x);System.out.println(y);}
}- 由于浮點數(shù)存在運算誤差,所以比較兩個浮點數(shù)是否相等常常會出現(xiàn)錯誤的結(jié)果。正確的比較方法是判斷兩個浮點數(shù)之差的絕對值是否小于一個很小的數(shù):
// 比較x和y是否相等,先計算其差的絕對值:
double r = Math.abs(x - y); //Math.abs()是求絕對值的
// 再判斷絕對值是否足夠小:
if (r < 0.00001) {// 可以認(rèn)為相等
} else {// 不相等
}浮點數(shù)在內(nèi)存的表示方法和整數(shù)相比更加復(fù)雜。Java的浮點數(shù)完全遵循IEEE-754標(biāo)準(zhǔn),這也是絕大多數(shù)計算機(jī)平臺都支持的浮點數(shù)標(biāo)準(zhǔn)表示方法。
類型提升
如果參與運算的兩個數(shù)其中一個是整型,那么整型可以自動提升到浮點型:
public class Main {public static void main(String[] args) {int n = 5;double d = 1.2 + 24.0 / n; // 6.0System.out.println(d);}
}需要特別注意,在一個復(fù)雜的四則運算中,兩個整數(shù)的運算不會出現(xiàn)自動提升的情況。
例如:
double d = 1.2 + 24 / 5; // d = 5.2 【 24 / 5= 4.8(int)=4 】計算結(jié)果為5.2,原因是編譯器計算24 / 5這個子表達(dá)式時,按兩個整數(shù)進(jìn)行運算,結(jié)果仍為整數(shù)4。
溢出
整數(shù)運算在除數(shù)為0時會報錯,而浮點數(shù)運算在除數(shù)為0時,不會報錯,但會返回幾個特殊值:
NaN表示Not a NumberInfinity表示無窮大-Infinity表示負(fù)無窮大
例如:
double d1 = 0.0 / 0; // NaN
double d2 = 1.0 / 0; // Infinity
double d3 = -1.0 / 0; // -Infinity這三種特殊值在實際運算中很少碰到,我們只需要了解即可。
強制轉(zhuǎn)型
可以將浮點數(shù)強制轉(zhuǎn)型為整數(shù)。在轉(zhuǎn)型時,浮點數(shù)的小數(shù)部分會被丟掉。如果轉(zhuǎn)型后超過了整型能表示的最大范圍,將返回整型的最大值。例如:
int n1 = (int) 12.3; // 12
int n2 = (int) 12.7; // 12
int n2 = (int) -12.7; // -12
int n3 = (int) (12.7 + 0.5); // 13
int n4 = (int) 1.2e20; // 2147483647 ,因為超過了整型能表示的最大范圍,所以放回整型的最大值注意:1.2e20 = 1.2 x 1020
如果轉(zhuǎn)型后超過了整型能表示的最大范圍,將返回整型的最大值。
如果要進(jìn)行四舍五入,可以對浮點數(shù)加上0.5再強制轉(zhuǎn)型:
// 四舍五入
public class Main {public static void main(String[] args) {double d = 2.6;int n = (int) (d + 0.5); //加上5,然后能進(jìn)位的進(jìn)位,不能進(jìn)位的被丟棄System.out.println(n);}
}PS:想要關(guān)注更多最新文章可以關(guān)注我的微信【苦逼的學(xué)生仔】
總結(jié)
以上是生活随笔為你收集整理的java负数右移_收入囊中篇---Java程序基础(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: img 在video上面_HTML,im
- 下一篇: 谁有反伤的技能《军团效果不算》