keywords:number
,toExponential
,toPrecision
,Number.EPSILON
,isInteger
,isSafeInteger
數字 Number
- JavaScript 只有一種數值型別 number,包含整數 ( integer ) 及帶有小數點的十進位數字,但是 JavaScript 並沒有真正的整數
- 根據最新的 ECMAScript 2021 數值型別有兩個:Number and BigInt.
- JavaScript number 的實作是基於 IEEE754 這個標準,通常被稱為浮點數,JavaScript 使用的是此標準的雙精度格式( 也就是 64 位元的二進位數字 )
非常大或非常小的 number 預設會以指數形式輸出,與 toExponential() ( 回傳數字轉成『 科學記數法 』格式的一個字串 ) 方法的輸出格式相同
let a = 6E10; a; // 60000000000 a.toExponential(); // 6e+10 let b = a * a; b; // 3.6e+21 b.toExponential(); // '3.6e+21'
number 可以用 Number 物件包裹器取用內建 Number.prototype 中的方法, toFixed(..) 方法能指定要用幾個小數位數來表示一個值
let a = 98.73; a.toFixed(0); // '99' a.toFixed(1); // '98.7' a.toFixed(2); // '98.73 a.toFixed(3); // '98.730' 🚩 這裡輸出是 number 的 string 表示值
toPrecision(..) 是以多少位的有效數字來表示該值
let a = 98.73; a.toPrecision(0); // RangeError: toPrecision() argument must be between 1 and 100 a.toPrecision(1) // '1e+2' 1e+2; // 100 a.toPrecision(2); // '99' a.toPrecision(3); // '98.7' a.toPrecision(4); // '98.73' a.toPrecision(5); // '98.730'
. 是一個有效的數值字元,它被解讀為 number 字面值的一部分,而非解讀為一個特性存取器
98.toFixed(3); // SyntaxError:Invalid or unexpected token (98).toFixed(3); // '98.000' 0.98.toFixed(3); // '0.980' 98..toFixed(3); // '98.000' 98 .toFixed(3) // '98.000' ( 注意那個空格 ) 但是請避免這樣做
- 在任何基本型別值 ( primitive values ) 上直接取用方法是相當少見的,只是不常見不代表好或壞
小的十進位值
- 使用二進位浮點數字最惡名昭彰的副作用 ( 使用 IEEE 754 的所有語言皆是如此 ) 但大部分都認為只有 JavaScript 有這個問題
0.1 + 0.2 === 0.3; // false what the fuck? 😮
以二進位浮點數字表示的 0.1 及 0.2 並不精確 ( not exact ) 所以相加時,不會剛好是 0.3 但是結果非常接近
0.1 + 0.2; // 0.30000000000000004
- 如果要比較小數位的大小,最廣為接受的實務做法是使用一個很小的約整誤差值作為比較的容許值,這個很小的值稱為 machine epsilon
可以使用 Number.EPSILON 來比較兩個 number 是否在約整誤差的內許範圍內
Number.EPSILON; // 2.220446049250313e-16
function numbersEqual(n1,n2) {
return Math.abs(n1-n2) < Number.EPSILON;
}
let a = 0.1 + 0.2;
let b = 0.3;
numbersEqual(a,b); // true
numbersEqual(0.0000001,0.0000002); // true
安全的整數範圍
完整的 number 整數有一個安全地範圍,也就是保證所請求的值可以毫無歧義地精確,約 2⁵³ -1 即 9007199254740991,而在 ES6 中它被定義為 Number.MAX_SAFE_INTEGER
測試整數
JavaScript ES6 提供一個可以測試是否為整數的方法,.isInteger()
Number.isInteger(98); // true Number.isInteger(98.000); // true Number.isInteger(98.73); // false Number.isInteger(98.); // true Number.isInteger(.98); // false
測試是否為安全整數,可以使用 ES6 規格指定的方法 .isSafeInteger()
Number.isSafeInteger(Number.MAX_SAFE_INTEGER); // true Number.isSafeInteger(Math.pow(2,53)); // false Number.isSafeInteger(Math.pow(2,53)-1); // true
- Math.pow() 函式回傳 base 的 exponent 次方(幂)值