在Java中,應用程式由類別組成,類別由方法和變數組成。變數又分為原始變數和引用變數。 Java中的變數有8種類型,除了
boolean
和之外char
,它們分為以下類型:
- 整數:
byte
、short
和int
;long
- 浮點數(也稱為實數):
float
和double
。
long
,範圍從 -9223372036854775808 到 9223372036854775807。浮點數中,double
的範圍是 1.7e-308 到 1.7e+308。您可以在本文中閱讀有關實數的更多資訊。但是如果我們需要儲存超出可接受範圍的數字怎麼辦?在這種情況下,我們需要BigInteger
和BigDecimal
。
Java 中的大整數
Java 類別BigInteger
用作任意長度整數值的模擬,沒有 long 的 64 位元限制。此外,它是 類別 的後代Number
,就像數字簡單類型的標準包裝器 - 、 、Integer
等等Long
-因此它具有導致簡單類型的方法的實現: Byte
Double
BigInteger value = new BigInteger("32145");
int intValue = value.intValue();//32145
long longValue = value.longValue();//32145
double doubleValue = value.doubleValue();//32145.0
我們立即看到這樣一個物件的創建,BigInteger
並將我們的值傳遞給建構函數,但以字串格式。值得注意的是,他擁有不只一位設計師,但適合所有場合。如果基本類型無法容納來自 的全部數據BigInteger
,則資料將被截斷為該基本類型的範圍。但同時,這些方法也有類似的方法(intValueExact()
等等longValueExact()
),唯一的差異是,如果進行轉換的簡單型別不適應資料範圍,則會拋出ArithmeticException。
大整數常數
對於內部使用,該類別具有常數:BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
這些是常量對象BigInteger
,其值分別為0
、1
和10
。
大整數方法
這個類別的主要特徵之一是它充滿了在 Java 中實現標準算術運算的方法。例如:-
求和運算:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.add(secondValue);//73461
-
乘法運算:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.multiply(secondValue);//1347530670
-
一個數除以另一個數求餘數的運算:
BigInteger firstValue = new BigInteger("37995"); BigInteger secondValue = new BigInteger("35466"); BigInteger resultValue = firstValue.remainder(secondValue);//2529
-
取得數字的絕對值(即模數、無符號):
BigInteger firstValue = new BigInteger("-37995"); BigInteger resultValue = firstValue.abs();//37995
-
mod計算的運算:
BigInteger firstValue = new BigInteger("-34"); BigInteger secondValue = new BigInteger("5"); BigInteger resultValue = firstValue.mod(secondValue); //1
-
取得一個隨機數並指定結果值將使用的位數:
BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211 BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
-
以位移位運算(this >> n)
左移:
BigInteger firstValue = new BigInteger("5"); BigInteger firstResultValue = firstValue.shiftLeft(3);//40
右移:
BigInteger secondValue = new BigInteger("34"); BigInteger secondResultValue = secondValue.shiftRight(2); //8
Java 中的 BigDecimal
當我們需要任意長度的實數時,使用Java類別 -BigDecimal
. 通常,它用於處理財務而不是double
,因為它提供了更多的自訂選項。與 和 一樣BigInteger
,BigDecimal
是一個類別的後代Number
,並且具有將物件的值傳回為特定基元類型的方法:
BigDecimal value = new BigDecimal(35563.3);
long longValue = value.longValue();//35563
double doubleValue = value.doubleValue();//35563.3
正如我們所看到的,當減少到 時long
,僅保留整數部分,而小數部分被丟棄。
BigDecimal 建構函數
我們將仔細研究構造函數BigDecimal
,因為該類別有更廣泛的選擇。有些建構函式可讓您以不同的方式設定物件的值(透過傳遞int
、long
、double
,String
甚至BigInteger
),而有些建構函式允許這樣做。設定已建立的物件的設定(舍入方法、小數位數):
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
這裡一切都清楚了,我們直接設定我們想要看到的數值和小數位數。
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
這個建構函數的結果可能非常不可預測,因為我們指定了一個 double,它本質上是一個非常模糊的類型。因此,一般建議在構造函數中使用String
。
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
我們設定了double
,但同時我們也設定了一個描述舍入規則的參數(其中包含小數位數和捨入的演算法)。
char[] arr = new String("455656.545").toCharArray();
BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
我們設定一個字元數組,從哪個元素中取得物件的值以及我們取得多少個元素。
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
我們採用一個已經存在的對象BigInteger
,設定小數位數。
大十進制方法
該類別BigDecimal
還包含各種算術運算的方法,但BigInteger
它沒有處理位的方法,例如 . 但無論如何,主要特點BigDecimal
是處理浮點數的彈性。讓我們來看看一些讓我們能夠掌握實數的技巧:
-
我們得到精度(數字的數量):
BigDecimal value = new BigDecimal("454334.34334"); int result = value.precision();//11
-
設定小數位數和舍入規則:
BigDecimal firstValue = new BigDecimal(3445.544445); BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_CEILING);//3445.545
下面我們將仔細研究設定舍入規則的常數。
-
除以
BigDecimal
另一個BigDecimal
,同時指明所需的小數位數和捨入規則:BigDecimal firstValue = new BigDecimal("455656.545"); BigDecimal secondValue = new BigDecimal(3445.544445); BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
-
將小數點向右/向左移動一定位數:
BigDecimal value = new BigDecimal("455656.545"); BigDecimal firstResult = value.movePointRight (2);//45565654.5 BigDecimal secondResult = value.movePointLeft (2);//4556.56545
-
修剪尾隨零:
BigDecimal value = new BigDecimal("45056.5000"); BigDecimal result = value.stripTrailingZeros();//45056.5
如果實部全為零且整個部分也全為零(或根本沒有小數位),那麼:
BigDecimal value = new BigDecimal("450000.000"); BigDecimal result = value.stripTrailingZeros();//4.5E+5
BigDecimal 舍入規則
要設定舍入規則,在內部BigDecimal
我們可以看到描述舍入演算法的特殊常數: ROUND_UP
- 從零捨入,向實部捨入:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_UP );//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UP );//-2.5
ROUND_DOWN
— 四捨五入到零,即截斷實部:
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_DOWN );//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_DOWN );//-2.6
ROUND_CEILING
— 四捨五入至正無窮大。也就是說,如果我們的數字是正數,則 -> ROUND_UP
,如果負數,則 ->ROUND_DOWN
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_CEILING);//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_CEILING);//-2.5
ROUND_FLOOR
- 四捨五入到負無窮大,也就是說,如果我們的數字是正數,則 -> ROUND_DOWN
,如果負數,則 ->ROUND_UP
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_FLOOR);//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_FLOOR);//-2.6
對於所考慮的值,我們將把這個截斷小數位的最接近的數字視為所考慮的數字的最近鄰居。例如,2.43 會比 2.5 更接近 2.4,但 2.48 會更接近 2.5。 ROUND_HALF_DOWN
- 四捨五入到「最近的鄰居」。如果兩個鄰居與特定值等距,則四捨五入到零。等距是指,例如,當四捨五入的數字為 5 時,與 0 和 10 的距離相同):
BigDecimal firstValue = new BigDecimal("2.58");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.6
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.5
ROUND_HALF_UP
— 向「最近鄰居」捨去的模式。如果兩個鄰居等距,則進行舍入(這與我們在學校教的捨入相同):
BigDecimal firstValue = new BigDecimal("2.53");
BigDecimal firstResult = firstValue.setScale(1, BigDecimal.ROUND_HALF_UP );//2.5
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_UP );//2.6
ROUND_HALF_EVEN
— 如果兩個鄰居不等距,則四捨五入到「最近的鄰居」。在這種情況下,如果要捨入的數字前面是奇數,則向上捨入,如果是偶數,則向下捨入:
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
我們得到這個結果是因為在四捨五入時,5 會查看前一個數字 2,發現它是偶數,就會向下捨去。但如果:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
由於最後 5 個值查看前一個值並看到奇數,因此該舍入會向上舍入。結果,數字向上捨入為 6,之後下一個 6 也將捨去。但六不再看左邊的數字,因為這個數字明顯更靠近上方,結果最後的2加了1。- ROUND_UNNECESSARY
用於檢查該數字是否不需要四捨五入。也就是說,我們檢查數字是否具有所需的小數位數:
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult = firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
這裡一切都很好,該值有兩位數,我們檢查小數點後面只有兩位數。但如果:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
然後我們得到 - ArithmeticException
,因為被測試的值超出了指定的小數位數。但是如果我們檢查兩位小數,但實際上有一位,那麼就不會拋出異常,並且將丟失的數字簡單地用零補充:
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY );//2.500
我還想指出 y具有與常數、和BigDecimal
類似的常數。這是文件的連結。最後:正如您可能注意到的那樣,當對對象和執行操作時,我們不會更改舊對象,而是總是獲取新對象。這告訴我們,它們在創建後是不可更改的,就像 一樣。換句話說,它們的所有方法都不能改變對象的內部狀態;最多只能傳回一個新對象,其參數由我們正在使用的函數指定。 BigInteger ZERO
ONE
TEN
BigInteger
BigDecimal
immutable
String
GO TO FULL VERSION