JavaScript 是一種弱類(lèi)型語(yǔ)言,其浮點(diǎn)數(shù)的比較會(huì)讓開(kāi)發(fā)者們遇到一些意外的問(wèn)題。例如:類(lèi)似于 0.1 + 0.2 === 0.3 的比較通常會(huì)返回 false。因此,本文將深入探究 JavaScript 中浮點(diǎn)數(shù)比較的問(wèn)題,通過(guò)大量案例和說(shuō)明,為讀者詳細(xì)解析這一問(wèn)題。
在 JavaScript 中,浮點(diǎn)數(shù)的比較幾乎都涉及到精度問(wèn)題。例如,0.1 + 0.2 返回的是 0.30000000000000004 而不是 0.3。這是由于內(nèi)部使用二進(jìn)制存儲(chǔ)的浮點(diǎn)數(shù)精度有限,無(wú)法無(wú)損地存儲(chǔ)所有的十進(jìn)制浮點(diǎn)數(shù)。這就需要我們對(duì)比較時(shí)的精度要求有一個(gè)清晰的認(rèn)識(shí)。
下面是一些針對(duì) JavaScript 浮點(diǎn)數(shù)比較精度的示例:
// 精度要求極高情況下建議使用 toFixed 0.1 + 0.2 === 0.3 // false (0.1 + 0.2).toFixed(1) === 0.3.toFixed(1) // true // 數(shù)字過(guò)大或過(guò)小時(shí)會(huì)出現(xiàn)精度問(wèn)題 0.0000001 + 0.0000002 === 0.0000003 // false (0.0000001 + 0.0000002).toFixed(7) === 0.0000003.toFixed(7) // true // 浮點(diǎn)數(shù)出現(xiàn)了極小的差異 1.0000000000000003 === 1 // true 1.0000000000000007 === 1 // true,但是當(dāng)大于等于 1.0000000000000008 時(shí)返回 false // 浮點(diǎn)數(shù)默認(rèn)具有toFixed精度控制功能 1.005.toFixed(2) === '1.01' // true 1.09.toFixed(1) === '1.1' // true 1.099.toFixed(1) === '1.1' // true 1.05.toFixed(1) === '1.0' // true 1.051.toFixed(1) === '1.1' // true // 使用 Number.EPSILON 解決精度問(wèn)題 function numbersCloseEnoughToEqual(n1, n2) { return Math.abs(n1 - n2)< Number.EPSILON; } numbersCloseEnoughToEqual(0.1 + 0.2, 0.3); // true上述代碼中,我們通過(guò)利用 toFixed 來(lái)保留指定小數(shù)位,來(lái)解決比較大的精度問(wèn)題;另一方面,我們則是運(yùn)用了 Number.EPSILON 常量,該常量表示一個(gè)可忽略的浮點(diǎn)數(shù)精度范圍(通常是 2^-52),使我們可以通過(guò)判定浮點(diǎn)數(shù)差異是否足夠小來(lái)進(jìn)行比較。 除上述方法外,我們還可以通過(guò) Math.round、Math.floor、Math.ceil 等函數(shù)對(duì)數(shù)值進(jìn)行舍入,在進(jìn)行比較時(shí)大大降低精度誤差。 總之,在 JavaScript 中進(jìn)行浮點(diǎn)數(shù)比較時(shí),我們需要注意比較的精度要求,并且選擇合適的方法來(lái)進(jìn)行比較,從而避免出現(xiàn)精度誤差的問(wèn)題。