前言
本文內容選自Java核心技術卷1 第10版,感興趣的小伙伴可以自行閱讀原書,以下內容為本人學習后摘取的片段與大家分享。
正文
3.3.2 浮點類型
所有的浮點數值計算都遵循 IEEE 754 規范。具體來說,下面是用于表示溢出和出錯情況的三個特殊的浮點數值:
- 正無窮大
- 負無窮大
- NaN (不是一個數字)
例如,一正整數除以 0 的結果為正無窮大。計算 0/0 或者負數的平方根結果為 NaN。
常量 Double_POSITIVE_INFINITY、 Double.NEGATIVEJNFINITY 和 Double.NaN ( 以及相應的 Float 類型的常量) 分別表示這三個特殊的值, 但在實際應用中很少遇到。
特別要說明的是, 不能這樣檢測一個特定值是否等于 Double.NaN:
if (x == Double.NaN) // is never true
所有“ 非數值” 的值都認為是不相同的。然而,可以使用 Double.isNaN 方法:
if (Double.isNaN(x)) // check whether x is "not a number"
警告: 浮點數值不適用于無法接受舍入誤差的金融計算中。 例如,命令
System.out.println(2.0 - 1.1)
將打印出 0.8999999999999999, 而不是人們想象的 0.9。這種舍入誤差的主要原因是浮點數值采用二進制系統表示, 而在二進制系統中無法精確地表示分數 1/10。這就好像十進制無法精確地表示分數 1/3 一樣。如果在數值計算中不允許有任何舍入誤差,就應該使用 BigDecimal 類。
并且,NaN類型也不等于自己,嘗試運行以下代碼:
System.out.println(Double.NaN == Double.NaN); // is false
3.5.1 數學函數與常量
在 Math類中,包含了各種各樣的數學函數。在編寫不同類別的程序時,可能需要的函數也不同。
要想計算一個數值的平方根, 可以使用 sqrt 方法:
double x = 4;
double y = Math.sqrt(x);
System.out.println(y); // prints 2.0
注釋: println 方法和 sqrt 方法存在微小的差異。println 方法處理 System.out 對象。但是,Math 類中的 sqrt 方法處理的不是對象,這樣的方法被稱為靜態方法。
在 Java中,沒有冪運算, 因此需要借助于 Math 類的 pow 方法。語句:
double y = Math.pow(x, a);
將 y 的值設置為 x 的 a 次冪( xa)。pow 方法有兩個 double 類型的參數, 其返回結果也為double 類型。
floorMod 方法的目的是解決一個長期存在的有關整數余數的問題??紤]表達式 n % 2。所有人都知道, 如果 n 是偶數, 這個表達式為 0 ; 如果 n 是奇數, 表達式則為 1。當然, 除非 n 是負數 如果 n 為負,這個表達式則為 -1。為什么呢? 設計最早的計算機時,必須有人制定規則,明確整數除法和求余對負數操作數該如何處理。數學家們幾百年來都知道這樣一個最優(或“ 歐幾里德”)規則:余數總是要 ≥0。不過, 最早制定規則的人并沒有翻開數學書好好研究,而是提出了一些看似合理但實際上很不方便的規則。
下面考慮這樣一個問題: 計算一個時鐘時針的位置。這里要做一個時間調整, 而且要歸一化為一個 0 ~ 11 之間的數。 這很簡單:(position + adjustment) % 12。不過, 如果這個調整為負會怎么樣呢? 你可能會得到一個負數。所以要引入一個分支, 或者使用((position + adjustment) % 12 + 12) % 12。不管怎樣, 總之都很麻煩。
floorMod 方法就讓這個問題變得容易了:floorMod(position + adjustment, 12) 總會得到一個 0 ~ 11 之間的數。
(遺憾的是,對于負除數,floorMod 會得到負數結果,不過這種情況在實際中很少出現。)
3.5.2 數值類型之間的轉換
經常需要將一種數值類型轉換為另一種數值類型。圖 3-1 給出了數值類型之間的合法轉換。
在圖 3-1 中有 6 個實心箭頭,表示無信息丟失的轉換;有 3 個虛箭頭, 表示可能有精度損失的轉換。 例如,123 456 789 是一個大整數, 它所包含的位數比 float 類型所能夠表達的位數多。 當將這個整型數值轉換為 float 類型時, 將會得到同樣大小的結果,但卻失去了一定的精度。
int n = 123456789;
float f = n; // f is 1.23456792E8
當使用上面兩個數值進行二元操作時(例如 n + f,n 是整數, f 是浮點數,) 先要將兩個操作數轉換為同一種類型,然后再進行計算。
- 如果兩個操作數中有一個是 double 類型, 另一個操作數就會轉換為 double 類型。
- 否則,如果其中一個操作數是 float 類型,另一個操作數將會轉換為 float 類型。
- 否則, 如果其中一個操作數是 long 類型, 另一個操作數將會轉換為 long 類型。
- 否則, 兩個操作數都將被轉換為 int 類型。

浙公網安備 33010602011771號