您當前的位置:首頁 > 舞蹈

收入囊中篇---Java程式基礎(二)

作者:由 東榆Tondy 發表于 舞蹈時間:2020-03-18

前言:

本篇是接著上一篇更新的,如果沒有閱讀上一篇的話,可以查閱或回顧一下。

1、收入囊中篇——-Java基礎必備知識(一)

2、收入囊中篇——-Java程式基礎(二)

Java程式基礎目錄

1、Java的基本結構

2、變數和資料結構

變數

基本資料型別

整型

浮點型

布林型別

字元型別

常量

var關鍵字

變數的作用範圍

小結

3、整數運算(本篇內容)

溢位

簡潔的運算子

自增/自減

移位運算

位運算

運算優先順序

型別自動提升與強制轉型

小結

4、浮點數運算(本篇內容)

型別提升

溢位

強制轉型

練習:

小結

5、布林運算

```

短路運算

三元運算子

練習:

小結 ```

6、字元和字串

```

字元型別

字串型別

字串連線

多行字串

不可變特性

空值null

練習:

小結 ```

7、陣列型別

```

字串陣列

小結 ```

3、整數運算

Java的整數運算遵循四則運算規則,可以使用任意巢狀的小括號。四則運算規則和初等數學一致。例如:

//四則運算

public

class

Main

{

public

static

void

main

String

[]

args

{

int

i

=

100

+

200

*

99

-

88

);

// 3300

int

n

=

7

*

5

+

i

-

9

));

// 23072

System

out

println

i

);

System

out

println

n

);

}

}

//從左往右先乘除,後加減依次進行

收入囊中篇---Java程式基礎(二)

整數的數值表示不但是精確的,而且整數運算永遠是精確的,即使是除法也是精確的,因為兩個整數相除只能得到結果的整數部分:

int

x

=

12345

/

67

// 184 ,整型只能夠得到整數

求餘運算使用

%

int

y

=

12345

%

67

// 12345÷67的餘數是17

特別注意:整數的除法對於除數為0時執行時將報錯,但編譯不會報錯。

溢位

要特別注意,整數由於存在範圍限制,如果計算結果超出了範圍,就會產生溢位,而溢位不會出錯,卻會得到一個奇怪的結果:

//運算溢位

public

class

Main

{

public

static

void

main

String

[]

args

{

int

x

=

2147483640

int

y

=

15

int

sum

=

x

+

y

System

out

println

sum

);

// -2147483641 ,正數相加竟然成為了負數

}

}

收入囊中篇---Java程式基礎(二)

要解釋上述結果,我們把整數

2147483640

15

換成二進位制做加法:

收入囊中篇---Java程式基礎(二)

由於最高位計算結果為

1

,因此,加法結果變成了一個負數。

要解決上面的問題,可以把

int

換成

long

型別,由於

long

可表示的整型範圍更大,所以結果就不會溢位:

//運算正常

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, 相當於 n = n + 100;

n

-=

100

// 3309, 相當於 n = n - 100;

自增/自減

Java還提供了

++

運算和

——

運算,它們可以對一個整數進行加1和減1的操作:

// 自增/自減運算

public

class

Main

{

public

static

void

main

String

[]

args

{

int

n

=

3300

n

++

// 3301, 相當於 n = n + 1;

n

——

// 3300, 相當於 n = n - 1;

int

y

=

100

+

++

n

);

// 不要這麼寫

System

out

println

y

);

}

}

收入囊中篇---Java程式基礎(二)

注意

++

寫在前面和後面計算結果是不同的,

++n

表示先加1再引用n,

n++

表示先引用n再加1。不建議把

++

運算混入到常規運算中,容易自己把自己搞懵了。

移位運算

在計算機中,整數總是以二進位制的形式表示。例如,

int

型別的整數

7

使用4位元組表示的二進位制如下:

00000000 0000000 0000000 00000111

可以對整數進行移位運算。對整數

7

左移1位將得到整數

14

,左移兩位將得到整數

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

,因此結果變成了負數。

類似的,對整數28進行右移,結果如下:

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

如果對一個負數進行右移,最高位的

1

不動,結果仍然是一個負數:

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

對比了兩種的移位運算之後,我客觀總結一下>>(右移)使用1來填補,<<(左移)使用0來填補。

如果從數學原理來理解的話就是,左移是滿2進1,原位補0。右移是減1退位,原位補1。

還有一種不帶符號的右移運算,使用

>>>

,它的特點是符號位跟著動,因此,對一個負數進行

>>>

右移,它會變成正數,原因是最高位的

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

型別進行移位時,會首先轉換為

int

再進行位移。

仔細觀察可發現,左移實際上就是不斷地×2,右移實際上就是不斷地÷2。

位運算

位運算是按位進行與、或、非和異或的運算。

與運算的規則是,必須兩個數同時為

1

,結果才為

1

n

=

0

&

0

// 0

n

=

0

&

1

// 0

n

=

1

&

0

// 0

n

=

1

&

1

// 1

或運算的規則是,只要任意一個為

1

,結果就為

1

n

=

0

|

0

// 0

n

=

0

|

1

// 1

n

=

1

|

0

// 1

n

=

1

|

1

// 1

非運算的規則是,

0

1

互換:

n

=

~

0

// 1

n

=

~

1

// 0

異或運算的規則是,如果兩個數不同,結果為

1

,否則為

0

n

=

0

^

0

// 0

n

=

0

^

1

// 1

n

=

1

^

0

// 1

n

=

1

^

1

// 0

對兩個整數進行位運算,實際上就是按位對齊,然後依次對每一位進行運算。例如:

public

class

Main

{

public

static

void

main

String

[]

args

{

int

i

=

167776589

// 00001010 00000000 00010001 01001101

int

n

=

167776512

// 00001010 00000000 00010001 00000000

// i&n = 00001010 00000000 00010001 00000000 = 167776512

System

out

println

i

&

n

);

// 167776512

}

}

收入囊中篇---Java程式基礎(二)

上述按位與運算實際上可以看作兩個整數表示的IP地址

10。0。17。77

10。0。17。0

,透過與運算,可以快速判斷一個IP是否在給定的網段內。

運算優先順序

在Java的計算表示式中,運算優先順序從高到低依次是:

()

~

++

——

*

/

%

+

-

<<

>>

>>>

&

|

+=

-=

*=

/=

記不住也沒關係,只需要加括號就可以保證運算的優先順序正確。

型別自動提升與強制轉型

在運算過程中,如果參與運算的兩個數型別不一致,那麼計算結果為較大型別的整型。例如,

short

int

計算,結果總是

int

,原因是

short

首先自動被轉型為

int

// 型別自動提升與強制轉型

public

class

Main

{

public

static

void

main

String

[]

args

{

short

s

=

1234

int

i

=

123456

int

x

=

s

+

i

// s自動轉型為int

short

y

=

s

+

i

// 編譯錯誤! 因為int型一般情況下是不可以轉化成為short型別的

}

}

收入囊中篇---Java程式基礎(二)

但是也還是可以將結果強制轉型,即將大範圍的整數轉型為小範圍的整數。強制轉型使用

(型別)

,例如,將

int

強制轉型為

short

int

i

=

12345

//12345為int型

short

s

=

short

i

// 12345為short型

要注意,超出範圍的強制轉型會得到錯誤的結果,原因是轉型時,

int

的兩個高位位元組直接被扔掉,僅保留了低位的兩個位元組。

例如:7(int)=0111(int) <————> 7(short)= 11(short)

//強制轉換型別

public

class

Main

{

public

static

void

main

String

[]

args

{

int

i1

=

1234567

short

s1

=

short

i1

// -10617

System

out

println

s1

);

int

i2

=

12345678

short

s2

=

short

i2

// 24910

System

out

println

s2

);

}

}

收入囊中篇---Java程式基礎(二)

因此,強制轉型的結果很可能是錯的。

收入囊中篇---Java程式基礎(二)

收入囊中篇---Java程式基礎(二)

小結

整數運算的結果永遠是精確的;

運算結果會自動提升;

可以強制轉型,但超出範圍的強制轉型會得到錯誤的結果;

應該選擇合適範圍的整型(

int

long

),沒有必要為了節省記憶體而使用

byte

short

進行整數運算。

4、浮點數運算

浮點數運算和整數運算相比,只能進行加減乘除這些數值計算,不能做位運算和移位運算。

在計算機中,浮點數雖然表示的範圍大,但是,浮點數有個非常重要的特點,就是浮點數常常無法精確表示。

舉個栗子:

浮點數

0。1

在計算機中就無法精確表示,因為十進位制的

0。1

換算成二進位制是一個無限迴圈小數,很顯然,無論使用

float

還是

double

,都只能儲存一個

0。1

的近似值。但是,

0。5

這個浮點數又可以精確地表示。

因為浮點數常常無法精確表示,因此,浮點數運算會產生誤差:

//浮點數運算誤差

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

);

}

}

收入囊中篇---Java程式基礎(二)

由於浮點數存在運算誤差,所以比較兩個浮點數是否相等常常會出現錯誤的結果。正確的比較方法是判斷兩個浮點數之差的絕對值是否小於一個很小的數:

// 比較x和y是否相等,先計算其差的絕對值:

double

r

=

Math

abs

x

-

y

);

//Math。abs()是求絕對值的

// 再判斷絕對值是否足夠小:

if

r

<

0。00001

{

// 可以認為相等

}

else

{

// 不相等

}

浮點數在記憶體的表示方法和整數相比更加複雜。Java的浮點數完全遵循IEEE-754標準,這也是絕大多數計算機平臺都支援的浮點數標準表示方法。

型別提升

如果參與運算的兩個數其中一個是整型,那麼整型可以自動提升到浮點型:

public

class

Main

{

public

static

void

main

String

[]

args

{

int

n

=

5

double

d

=

1。2

+

24。0

/

n

// 6。0

System

out

println

d

);

}

}

收入囊中篇---Java程式基礎(二)

需要特別注意,在一個複雜的四則運算中,兩個整數的運算不會出現自動提升的情況。

例如:

double

d

=

1。2

+

24

/

5

// d = 5。2 【 24 / 5= 4。8(int)=4 】

計算結果為

5。2

,原因是編譯器計算

24 / 5

這個子表示式時,按兩個整數進行運算,結果仍為整數

4

溢位

整數運算在除數為

0

時會報錯,而浮點數運算在除數為

0

時,不會報錯,但會返回幾個特殊值:

NaN

表示Not a Number

Infinity

表示無窮大

-Infinity

表示負無窮大

例如:

double

d1

=

0。0

/

0

// NaN

double

d2

=

1。0

/

0

// Infinity

double

d3

=

-

1。0

/

0

// -Infinity

這三種特殊值在實際運算中很少碰到,我們只需要瞭解即可。

強制轉型

可以將浮點數強制轉型為整數。在轉型時,浮點數的小數部分會被丟掉。如果轉型後超過了整型能表示的最大範圍,將返回整型的最大值。例如:

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

如果轉型後超過了整型能表示的最大範圍,將返回整型的最大值。

收入囊中篇---Java程式基礎(二)

如果要進行四捨五入,可以對浮點數加上0。5再強制轉型:

// 四捨五入

public

class

Main

{

public

static

void

main

String

[]

args

{

double

d

=

2。6

int

n

=

int

d

+

0。5

);

//加上5,然後能進位的進位,不能進位的被丟棄

System

out

println

n

);

}

}

收入囊中篇---Java程式基礎(二)

PS:想要關注更多最新文章可以關注我的微信【苦逼的學生仔】

標簽: 00000000  運算  浮點數  整數  int