算術運算子( - )
Java 語言提供了 7 個對整數和浮點值執行算術運算的運算子。
- 有兩個
+
運算子:- 二元加法運算子將一個數字新增到另一個數字。 (還有一個二進位制
+
運算子,它執行字串連線。這在另一個例子中描述。) - 除了觸發數字促銷之外,一元加運算子沒有任何作用(見下文)
- 二元加法運算子將一個數字新增到另一個數字。 (還有一個二進位制
- 有兩個
-
運算子:- 二元減法運算子從另一個數字中減去一個數字。
- 一元減運算子相當於從零減去其運算元。
- 二進位制乘法運算子(*)將一個數字與另一個數字相乘。
- 二元除法運算子(/)將一個數字除以另一個數字。
- 二進位制餘數 1 運算子(%)計算一個數除以另一個數時的餘數。
這通常被錯誤地稱為模數運算元。 剩餘是 JLS 使用的術語。 模數和餘數不是一回事。
運算元和結果型別以及數字提升
運算子需要數字運算元並生成數字結果。運算元型別可以是任何原始數字型別(即 byte
,short
,char
,int
,long
,float
或 double
)或 java.lang
中定義的任何數字包裝型別; 即(Byte
,Character
,Short
,Integer
,Long
,Float
或 Double
。
結果型別根據運算元或運算元的型別確定,如下所示:
- 如果其中一個運算元是
double
或Double
,則結果型別為double
。 - 否則,如果其中一個運算元是
float
或Float
,則結果型別為float
。 - 否則,如果其中一個運算元是
long
或Long
,則結果型別為long
。 - 否則,結果型別為
int
。這包括byte
,short
和char
運算元以及`int。
操作的結果型別確定如何執行算術運算,以及如何處理運算元
- 如果結果型別為
double
,則運算元被提升為double
,並且使用 64 位(雙精度二進位制)IEE 754 浮點運算執行操作。 - 如果結果型別為
float
,則運算元被提升為float
,並且使用 32 位(單精度二進位制)IEE 754 浮點運算執行操作。 - 如果結果型別為
long
,則將運算元提升為long
,並使用 64 位帶符號二進位制補碼二進位制整數運算執行操作。 - 如果結果型別為
int
,則將運算元提升為int
,並使用 32 位帶符號二進位制補碼二進位制整數運算執行操作。
促銷分兩個階段進行:
- 如果運算元型別是包裝型別,則運算元值將取消裝箱到相應基元型別的值。
- 如有必要,將基元型別提升為所需型別:
- 向
int
或long
推廣整數是無損失的。 - 將
float
推廣到double
是無損失的。 - 將整數提升為浮點值可能會導致精度損失。使用 IEE 768舍入到最接近語義執行轉換。
- 向
分裂的意義
/運算子將左側運算元 n
( 被除數 )和右側運算元 d
( 除數 ) 分開,併產生結果 q
( 商 )。
Java 整數除法向零舍入。該 JLS 第 15.17.2 規定如下 Java 的整數除法的行為:
為運算元
n
和d
生成的商是一個整數值q
,其大小儘可能大,同時滿足|d ⋅ q| ≤ |n|
。此外,當|n| ≥ |d|
和n
和d
具有相同的符號時,q
為正,但當|n| ≥ |d|
和n
和d
具有相反的符號時q
為負。
有幾個特例:
- 如果
n
是MIN_VALUE
,並且除數是 -1,則發生整數溢位,結果是MIN_VALUE
。在這種情況下不會丟擲異常。 - 如果
d
為 0,則丟擲`ArithmeticException。
Java 浮點除法有更多邊緣情況需要考慮。然而,基本的想法是結果 q
是最接近滿足 d . q = n
的值。
浮點除法永遠不會導致異常。相反,除以零的運算會產生 INF 和 NaN 值; 見下文。
餘數的含義
與 C 和 C++不同,Java 中的餘數運算子適用於整數和浮點運算。
對於整數情況,a % b
的結果定義為 r
,使得 (a / b) * b + r
等於 a
,其中/
,*
和+
是適當的 Java 整數運算子。這適用於所有情況,除非 b
為零。那種情況下,剩餘部分會產生一種情況。
從上面的定義可以得出,a % b
只有在 a
為負時才能為負數,只有當 a
為正時才為正。此外,a % b
的數量總是小於 b
的數量。
浮點餘數運算是整數情況的推廣。a % b
的結果是餘量 r
由數學關係 r = a - (b ⋅ q)
定義,其中:
q
是一個整數,- 只有當
a / b
為正時,只有當a / b
為負時才是負數,並且 - 它的大小儘可能大,而不超過
a
和b
的真正數學商的大小。
浮點餘數可以在邊緣情況下產生 INF
和 NaN
值,例如當 b
為零時; 見下文。它不會丟擲異常。
重要的提示:
作為計算通過
%
浮點餘數操作的結果是不相同的,通過由 IEEE 754. IEEE 754 定義的剩餘部分剩餘部分操作產生可以使用本Math.IEEEremainder
文庫的方法來計算。
整數溢位
Java 32 和 64 位整數值被簽名並使用二進位制補碼二進位制表示。例如,數字的範圍所能表述為(32 位)int
-2 31 通過 2 31 - 1。
當你新增,減去或多個兩個 N 位整數(N == 32 或 64)時,操作的結果可能太大而無法表示為 N 位整數。在這種情況下,操作會導致整數溢位,結果可以按如下方式計算:
- 執行數學運算以給出整數的中間二進位制補碼錶示。該表示將大於 N 位。
- 中間表示的底部 32 或 64 位用作結果。
應該注意的是,整數溢位在任何情況下都不會導致異常。
浮點 INF 和 NAN 值
Java 使用 IEE 754 浮點表示 float
和 double
。這些表示具有一些特殊值,用於表示超出實數域的值:
- 無限或 INF 值表示數字太大。
+INF
值表示過大且積極的數字。-INF
值表示過大和負數的數字。 - 無限期/非數字或 NaN 表示由無意義操作產生的值。
INF 值由導致溢位的浮動操作產生,或者由除以零產生。
通過將零除以零或計算零餘數零來產生 NaN 值。
令人驚訝的是,可以使用 INF 和 NaN 運算元執行算術而不會觸發異常。例如:
- 新增+ INF 和有限值會給出+ INF。
- 新增+ INF 和+ INF 會給出+ INF。
- 新增+ INF 和 -INF 會產生 NaN。
- 除以 INF 給出+0.0 或 -0.0。
- 具有一個或多個 NaN 運算元的所有操作都給出 NaN。
有關詳細資訊,請參閱 JLS 15 的相關小節。請注意,這主要是學術性的。對於典型的計算,INF
或 NaN
意味著出了問題; 例如,輸入資料不完整或不正確,或者計算程式設計錯誤。