算術運算子( - )

Java 語言提供了 7 個對整數和浮點值執行算術運算的運算子。

  • 有兩個+運算子:
    • 二元加法運算子將一個數字新增到另一個數字。 (還有一個二進位制+運算子,它執行字串連線。這在另一個例子中描述。)
    • 除了觸發數字促銷之外,一元加運算子沒有任何作用(見下文)
  • 有兩個 - 運算子:
    • 二元減法運算子從另一個數字中減去一個數字。
    • 一元減運算子相當於從零減去其運算元。
  • 二進位制乘法運算子(*)將一個數字與另一個數字相乘。
  • 二元除法運算子(/)將一個數字除以另一個數字。
  • 二進位制餘數 1 運算子(%)計算一個數除以另一個數時的餘數。

這通常被錯誤地稱為模數運算元。 剩餘是 JLS 使用的術語。 模數餘數不是一回事。

運算元和結果型別以及數字提升

運算子需要數字運算元並生成數字結果。運算元型別可以是任何原始數字型別(即 byteshortcharintlongfloatdouble)或 java.lang 中定義的任何數字包裝型別; 即(ByteCharacterShortIntegerLongFloatDouble

結果型別根據運算元或運算元的型別確定,如下所示:

  • 如果其中一個運算元是 doubleDouble,則結果型別為 double
  • 否則,如果其中一個運算元是 floatFloat,則結果型別為 float
  • 否則,如果其中一個運算元是 longLong,則結果型別為 long
  • 否則,結果型別為 int。這包括 byteshortchar 運算元以及`int。

操作的結果型別確定如何執行算術運算,以及如何處理運算元

  • 如果結果型別為 double,則運算元被提升為 double,並且使用 64 位(雙精度二進位制)IEE 754 浮點運算執行操作。
  • 如果結果型別為 float,則運算元被提升為 float,並且使用 32 位(單精度二進位制)IEE 754 浮點運算執行操作。
  • 如果結果型別為 long,則將運算元提升為 long,並使用 64 位帶符號二進位制補碼二進位制整數運算執行操作。
  • 如果結果型別為 int,則將運算元提升為 int,並使用 32 位帶符號二進位制補碼二進位制整數運算執行操作。

促銷分兩個階段進行:

  • 如果運算元型別是包裝型別,則運算元值將取消裝箱到相應基元型別的值。
  • 如有必要,將基元型別提升為所需型別:
    • intlong 推廣整數是無損失的。
    • float 推廣到 double 是無損失的。
    • 將整數提升為浮點值可能會導致精度損失。使用 IEE 768舍入到最接近語義執行轉換。

分裂的意義

/運算子將左側運算元 n被除數 )和右側運算元 d除數 ) 分開,併產生結果 q )。

Java 整數除法向零舍入。該 JLS 第 15.17.2 規定如下 Java 的整數除法的行為:

為運算元 nd 生成的商是一個整數值 q,其大小儘可能大,同時滿足|d ⋅ q| ≤ |n|。此外,當|n| ≥ |d|nd 具有相同的符號時,q 為正,但當|n| ≥ |d|nd 具有相反的符號時 q 為負。

有幾個特例:

  • 如果 nMIN_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 為負時才是負數,並且
  • 它的大小儘可能大,而不超過 ab 的真正數學商的大小。

浮點餘數可以在邊緣情況下產生 INFNaN 值,例如當 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 浮點表示 floatdouble。這些表示具有一些特殊值,用於表示超出實數域的值:

  • 無限或 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 的相關小節。請注意,這主要是學術性的。對於典型的計算,INFNaN 意味著出了問題; 例如,輸入資料不完整或不正確,或者計算程式設計錯誤。