亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

使用“機械極小值(machine epsilon)”作為比較的 容差 處理JS中小數的比較

標簽:
JavaScript

内容来自: You-dont-know-JS中类型与文法的第二章(值)

小数值

使用二进制浮点数的最出名(臭名昭著)的副作用是(记住,这是对 所有 使用 IEEE 754 的语言都成立的 —— 不是许多人认为/假装 仅 在 JavaScript 中存在的问题):

0.1 + 0.2 === 0.3; // false1

从数学的意义上,我们知道这个语句应当为 true。为什么它是 false

简单地说,0.10.2 的二进制表示形式是不精确的,所以它们相加时,结果不是精确地 0.3。而是 非常 接近的值:0.30000000000000004,但是如果你的比较失败了,“接近”是无关紧要的。

注意: JavaScript 应当切换到可以精确表达所有值的一个不同的 number 实现吗?有些人认为应该。多年以来有许多选项出现过。但是没有一个被采纳,而且也许永远也不会。它看起来就像挥挥手然后说 “已经改好那个 bug 了!” 那么简单,但根本不是那么回事儿。如果真有这么简单,它绝对在很久以前就被改掉了。

现在的问题是,如果一些 number 不能被 信任 为精确的,这不是意味着我们根本不能使用 number 吗? 当然不是

在一些应用程序中你需要多加小心,特别是在对付小数的时候。还有许多(也许是大多数?)应用程序只处理整数,而且,最大只处理到几百万到几万亿。这些应用程序使用 JS 中的数字操作是,而且将总是,非常安全 的。

要是我们 确实 需要比较两个 number,就像 0.1 + 0.20.3,而且知道这个简单的相等测试将会失败呢?

可以接受的最常见的做法是使用一个很小的“错误舍入”值作为比较的 容差。这个很小的值经常被称为“机械极小值(machine epsilon)”,对于 JavaScript 来说这种 number 通常为 2^-52(2.220446049250313e-16)

在 ES6 中,使用这个容差值预定义了 Number.EPSILON,所以你将会想要使用它,你也可以在前 ES6 中安全地填补这个定义:

if (!Number.EPSILON) {    Number.EPSILON = Math.pow(2,-52);
}123

我们可以使用这个 Number.EPSILON 来比较两个 number 的“等价性”(带有错误舍入的容差):

function numbersCloseEnoughToEqual(n1,n2) {
    return Math.abs( n1 - n2 ) < Number.EPSILON;
}var a = 0.1 + 0.2;var b = 0.3;

numbersCloseEnoughToEqual( a, b );                  // truenumbersCloseEnoughToEqual( 0.0000001, 0.0000002 );  // false123456789

可以被表示的最大的浮点值大概是 1.798e+308(它真的非常,非常,非常大!),它为你预定义为 Number.MAX_VALUE。在极小的一端,Number.MIN_VALUE 大概是 5e-324,它不是负数但是非常接近于0


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消