Google Guava與數學運算相關的類

數學:JDK未提供經過優化、全面測試的數學工具。

這個包com.google.common.math包含各種數學工具。

1.內容

  • 基本的獨立數學函數根據所涉及的主要數字類型分爲IntMathLongMathDoubleMathBigIntegerMath類。這些類具有並行結構,但每個類僅支持函數的相關子集。請注意,在com.google.common.primitives類(例如Ints)中可能會找到本質上數學性較低的類似函數。
  • 對於單個和成對的數據集,都提供了各種統計計算(平均值、中位數等)。從閱讀本概述開始,而不只是瀏覽Javadoc。
  • LinearTransformation表示形式y = mx + b的雙精度值之間的線性轉換;例如,英尺和米之間的轉換,或者開氏溫度與華氏度之間的轉換。

2.示例

int logFloor = LongMath.log2(n, FLOOR);

int mustNotOverflow = IntMath.checkedMultiply(x, y);

long quotient = LongMath.divide(knownMultipleOfThree, 3, RoundingMode.UNNECESSARY); // fail fast on non-multiple of 3

BigInteger nearestInteger = DoubleMath.roundToBigInteger(d, RoundingMode.HALF_EVEN);

BigInteger sideLength = BigIntegerMath.sqrt(area, CEILING);

3.爲什麼要使用這些?

  • 這些工具已經針對異常的溢出條件進行了詳盡的測試。在關聯文檔中已明確地指定了溢出語義(如果相關)。當前置條件失敗時,它會快速失敗。
  • 它們經過了基準測試和優化。雖然性能不可避免地取決於特定的硬件細節,但它們的速度與Apache Commons MathUtils中的類似函數相比——在某些情況下,甚至要好得多。
  • 它們被設計用來鼓勵可讀的、正確的編程習慣。IntMath.log2(x, CEILING)的含義是明確的,即使是隨意通讀也是顯而易見的。 32 - Integer.numberOfLeadingZeros(x - 1)的含義不是。

注意這些工具與GWT並不是特別兼容,由於溢出邏輯不同,它們也沒有針對GWT進行優化

4.整數類型的數學

這些工具主要處理三種整數類型:intlongBigInteger。這些類型的數學工具方便地命名爲IntMathLongMathBigIntegerMath

4.1校驗算法

我們爲IntMathLongMath提供了算術方法,這些方法在溢出時會快速失敗,而不是無視它們。

IntMath LongMath
IntMath.checkedAdd LongMath.checkedAdd
IntMath.checkedSubtract LongMath.checkedSubtract
IntMath.checkedMultiply LongMath.checkedMultiply
IntMath.checkedPow LongMath.checkedPow
IntMath.checkedAdd(Integer.MAX_VALUE, Integer.MAX_VALUE); // throws ArithmeticException

5.實值方法

IntMathLongMathBigIntegerMath支持多種具有“精確實值”的方法,但是會將其結果舍入爲整數。這些方法接受java.math.RoundingMode。這與JDK中使用的RoundingMode相同,並且是一個具有以下值的枚舉:

  • DOWN:向0方向舍入。(這是Java除法的行爲)
  • UP:向遠離0方向舍入。
  • FLOOR:向負無窮大方向舍入。
  • CEILING:向正無窮大方向舍入。
  • UNNECESSARY:不需要四捨五入;如果是,則通過拋出ArithmeticException快速失敗。
  • HALF_UP:舍入到最接近的一半,將x.5向遠離0方向舍入。
  • HALF_DOWN:舍入到最接近的一半,將x.5向0方向舍入。
  • HALF_EVEN:舍入到最接近的一半,將x.5向最接近的相鄰偶數方向舍入。

這些方法在使用時具有可讀性:例如,即使是隨意的通讀,divide(x, 3, CEILING)也是完全明確的。

此外,除了構造用於sqrt的初始近似值外,這些函數中的每一個內部都僅使用整數運算。

操作 IntMath LongMath BigIntegerMath
除法 divide(int, int, RoundingMode) divide(long, long, RoundingMode) divide(BigInteger, BigInteger, RoundingMode)
以2爲底的對數 log2(int, RoundingMode) log2(long, RoundingMode) log2(BigInteger, RoundingMode)
以10爲底的對數 log10(int, RoundingMode) log10(long, RoundingMode) log10(BigInteger, RoundingMode)
平方根 sqrt(int, RoundingMode) sqrt(long, RoundingMode) sqrt(BigInteger, RoundingMode)
BigIntegerMath.sqrt(BigInteger.TEN.pow(99), RoundingMode.HALF_EVEN);
   // returns 31622776601683793319988935444327185337195551393252

5.1附加功能

我們爲發現有用的其他一些數學函數提供了支持。

操作 IntMath LongMath BigIntegerMath
最大公約數 gcd(int, int) gcd(long, long) In JDK: BigInteger.gcd(BigInteger)
取模數(總是非負的,-5 mod 3爲1) mod(int, int) mod(long, long) In JDK: BigInteger.mod(BigInteger)
求冪(可能會溢出) pow(int, int) pow(long, int) In JDK: BigInteger.pow(int)
二次冪測試 isPowerOfTwo(int) isPowerOfTwo(long) isPowerOfTwo(BigInteger)
階乘(如果輸入太大,則返回MAX_VALUE factorial(int) factorial(int) factorial(int)
二項式係數(如果太大,則返回MAX_VALUE binomial(int, int) binomial(int, int) binomial(int, int)

6.浮點運算

JDK完全涵蓋了浮點算法,但是我們向DoubleMath添加了一些有用的方法。

方法 描述
isMathematicalInteger(double) 測試輸入是否是有限的和精確的整數。
roundToInt(double, RoundingMode) 將指定的數字舍入並將其強制轉換爲整數(如果它適合整數),否則將快速失敗。
roundToLong(double, RoundingMode) 將指定的數字舍入並將其強制轉換爲長整數(如果它適合長整數),否則將快速失敗。
roundToBigInteger(double, RoundingMode) 將指定數字舍入到BigInteger(如果有限),否則快速失敗。
log2(double, RoundingMode) 以2爲底的對數,並使用指定的RoundingMode舍入爲一個int整數。比Math.log(double)快。

本文參考:
MathExplained
guava-tests-math

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章