處理浮點數

Frontend SELF TW
等級 37 , 課堂 0
開放

1.1 浮點數的取整

浮點數在英文叫floating point number - 帶有小數點的數字:在美國小數和整數之間用點來分隔。這就是名稱float的由來。

如我們之前討論過的,把浮點數 (float) 轉成整數 (int) 時,它總是向下取整 - 小數部分會被丟掉。但很容易可以想像有時候需要將數字四捨五入到最近的整數或是直接向上取整。怎麼辦?

在 JavaScript 中,這種情況可以使用內建函數 round()。這個函數是早在Math庫創建之前就有的,所以它不屬於這個庫。向下和向上取整的函數在 math 庫中。

函數 Math.round()

函數 Math.round() 將數字四捨五入到最近的整數:

    
      Math.round(浮點數)
    
  

這個函數將返回一個與傳入的浮點數最近的整數。

範例:

命令 結果
let x = Math.round(4.1); 4
let x = Math.round(4.5); 5
let x = Math.round(4.9); 5

函數 Math.ceil()

函數 Math.ceil() 將數字向上取整:

命令 結果
let x = Math.ceil(4.1); 5
let x = Math.ceil(4.5); 5
let x = Math.ceil(4.9); 5

函數 Math.floor()

函數 Math.floor() 將數字向下取整:

命令 結果
let x = Math.floor(4.1); 4
let x = Math.floor(4.5); 4
let x = Math.floor(4.9); 4

如果你覺得難以記住這些命令,這裡有個小英語課程可以幫助你:

  • math — 數學
  • round — 圓形/取整
  • ceiling — 天花板
  • floor — 地板

1.2 浮點數的結構

在 JavaScript 中,number 類型可以存儲的值範圍是 -1.7*10308 到 +1.7*10308。這麼大的範圍是因為 number 類型的結構跟整數類型完全不同。 每個 number 類型的變量都包含兩個數字:第一個叫 尾數,而第二個叫做 指數

假設我們有一個數字 123456789 並把它存到一個 number 類型的變量裡。然後數字就會被轉換成 1.23456789*108,在 number 類型中會存儲兩個數字——1.234567898。紅色標記的是數字的“有效部分”(尾數),藍色是指數。

這種結構讓非常大的數字和非常小的數字都可以被存儲。但是因為數字的大小受限於 8 字節(64 位),部分位元用於存儲 指數(還有數字的符號和指數的符號),尾數的最大長度限制在 15 位數字。

這是一個非常簡化的浮點數結構介紹:更詳細的可以參見這個 鏈接

1.3 處理浮點數時的精度損失

在處理浮點數時要始終記住,浮點數是 不精確的。總會有 取整錯誤、十進制轉換成二進制的錯誤,還有最常見的 精度損失 在加減數字時不同量級。

對編程初學者來說,最後一種情況最容易造成意外。

如果從數字 109 中減去 1/109,我們得到的還是 109

相差太大的數字的減法 解釋
1000000000.000000000
-      0.000000001
1000000000.000000000
第二個數字太小了,它的有效部分被忽略了(灰色標出)。 紅色標記的是 15 位有效數字

怎麼說呢,編程不是數學。

1.4 比較浮點數的危險

程序員在比較浮點數時還會面臨另一個陷阱。因為在處理這些數字時有可能積累取整誤差,所以會有情況發生,浮點數應該相等卻不等。而反過來也一樣:數字應該不等,但它們相等。

例子:

命令 解釋
let a = 1000000000.0
let b = 0.000000001
let c = a – b
在變數 a 中的值是 1000000000.0
在變數 c 中的值是 1000000000.0
(變數 b 的數字太小)。

在上面的例子中,ac 不應該相等,但它們相等。

或者再看另一個例子:

命令 解釋
let a = 1.00000000000000001
let b = 1.00000000000000002
在變數 a 中的值是 1.0
在變數 b 中的值是 1.0

在實際操作中,對浮點數的比較是這樣的:

如果兩個數字的差值(絕對值)小於某個非常小的數,則它們被認為是相等的。

範例:

JavaScript
    
      let a = 0.00000000012;
      let b = 0.000000000011;

      if (Math.abs(a - b) < 0.00001) {
        console.log("相等");
      } else {
        console.log("不相等");
      }
    
  
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION