摘要:吐槽一句,大二的專業課數字邏輯電路終于用在工作上了。,整數位為,且精度只到十分位,因此是。如果是不限精度的話,轉換后的二進制數應該是無限循環。再看一下百科給出的標準因此,的類型,最高的位是符號位,接著的位是指數,剩下的位為有效數字。
用一句話概括就是:
EcmaScrpt規范定義Number的類型遵循了IEEE754-2008中的64位浮點數規則定義的小數后的有效位數至多為52位導致計算出現精度丟失問題!
如果你看不懂這句話,仔細閱讀本篇博客就對了!
首先看下10進制轉換為2進制的方法。
數字邏輯電路上的算法是 (0.1)10 = (0.0)2。
吐槽一句,大二的專業課數字邏輯電路終于用在工作上了。
0.1*2 = 0.2 ,整數位為0,且精度只到十分位,因此是0.0。
如果是不限精度的話,轉換后的二進制數應該是:0.000110011001100110011(0011)無限循環。
如果表示成一個奇怪的形式,則是 (-1)^0*1.100110011(0011)* 2^-4
上述式子可類比十進制科學計數法公式。
0.0001234567 = 1.234567 * 10^-4?
為什么要這樣表示?
-1的0次冪又是什么意思?
這是國際標準組織IEEE754對于浮點數表示方式的一種定義。
格式為;
(-1)^S x Mx 2^E
各符號的意思如下:
S,是符號位,決定正負,0時為正數,1時為負數。
M,是指有效位數,大于1小于2。
E,是指數位。
因此才有了下面的形式:
(-1)^0*1.100110011(無限循環0011) * 2^-4 S = 0,M = 1.100110011(無限循環0011),E =-4
對應的0.2為:
(-1)^0*1.100110011(無限循環0011) * 2^-3 S = 0 ,M = 1.100110011(無限循環0011),E =-3
那么這和javascript有什么關系呢?
因為IEEE754標準里,還有兩種特殊的定義。
IEEE 754規定,對于32位的浮點數,最高的1位是符號位S,接著的8位是指數E,剩下的23位為有效數字M。
對于64位的浮點數,最高的1位是符號位S,接著的11位是指數E,剩下的52位為有效數字M。
問題還是一樣,這和我們的javascript有什么關系呢?
因為javascript中Number類型,就是嚴格按照IEEE754標準來定義的。下面給出了最新版的ecma-262版本中關于Number類型的定義。
*6.1.6
The Number Type**
The Number type has exactly 18437736874454810627 (that is,?) values, representing the double-precision 64-bit format IEEE 754-2008 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is,?) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special??value.
再看一下wiki百科給出的IEEE754標準:
因此,javascript的Number類型, 最高的1位是符號位S,接著的11位是指數E,剩下的52位為有效數字M。
拿0.1舉例來說:
(-1)^01.100110011(無限循環0011) 2^-4
= 0,M = 1.100110011(無限循環0011),E =-4
這里的無限循環就有限了,循環位數最多只能有52位.
JS中的0.1,在引擎中運算時,實質上會編譯成:
1.1001100110011001100110011001100110011001100110011001*2^-4
0.2同理,會編譯成:
1.1001100110011001100110011001100110011001100110011001*2^- 3
拿出關鍵的指數部分和有效位部分:
-4??0.1001100110011001100110011001100110011001100110011001 ① -3 ?0.1001100110011001100110011001100110011001100110011001 ②·
①式轉化為純小數,小數最低位的1001被高位的0000擠出有效范圍,得到③式
②式轉化為純小數,小數最低位的001被高位的000擠出有效范圍,得到④式
原因是什么?
原因就是JS中的Number類型,二進制小數的有效位數只有52位,從0到51位(包括邊界)。
在chrome控制臺輸入(0.1).toString("2")并打印結果為:"0.0001100110011001100110011001100110011001100110011001101"
不多不少,小數部分剛好52位,與規范以及我們的猜想完全契合。
回到0.1+0.2===0.30000000000000004這個經典問題。
在EcmaScript中,無關Browser環境,還是Nodejs環境,0.1+0.2的實際計算過程如下:
? ?? 0.0000100110011001100110011001100110011001100110011001 ③ ? ? +0.0001001100110011001100110011001100110011001100110011 ④ --------------------------------------------------------------------------------------------------- ? ? =0.0100110011001100110011001100110011001100110011001100 ⑤
最后得到的⑤式其實0.300000000000000004(17位十進制數)的二進制形式。
這就是0.1+0.2 ===0.300000000000000004的原因。
雖然我們期望的理想結果是返回0.3,恰恰印證了現實往往很骨感的說法。
有沒有讓0.1+02返回為0.3的辦法呢?
因為不只是這一個精度丟失特例,還有很多情況都會造成精度丟失,比如:
0.3 / 0.1===2.9999999999999996以及0.7 * 180==125.99999999998等等。
那么有沒有辦法解決這個問題呢?
移步下一篇博客:如何解決0.1 +0.2===0.30000000000000004類問題
鳴謝單位:
https://segmentfault.com/a/1190000005022170
http://demon.tw/copy-paste/javascript-precision.html
http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html
http://www.css88.com/archives/7340#more-7340
http://www.ecma-international.org/ecma-262/8.0/index.html
https://en.wikipedia.org/wiki/Floating-point_arithmetic#Internal_representation
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89591.html
摘要:方法使用定點表示法來格式化一個數,會對結果進行四舍五入。該數值在必要時進行四舍五入,另外在必要時會用來填充小數部分,以便小數部分有指定的位數。如果數值大于,該方法會簡單調用并返回一個指數記數法格式的字符串。在環境中,只能是之間,測試版本為。 showImg(https://segmentfault.com/img/remote/1460000011913134?w=768&h=521)...
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
摘要:因此利用以及語法樹在代碼構建過程中重寫等符號,開發時直接以這樣的形式編寫代碼,在構建過程中編譯成,從而在開發人員無感知的情況下解決計算失精的問題,提升代碼的可讀性。 前言 你了解過0.1+0.2到底等于多少嗎?那0.1+0.7,0.8-0.2呢? 類似于這種問題現在已經有了很多的解決方案,無論引入外部庫或者是自己定義計算函數最終的目的都是利用函數去代替計算。例如一個漲跌幅百分比的一個...
摘要:簡介是目前最流行的深度學習框架。代表一個數學運算,簡稱,這里面包括了深度學習模型經常需要使用的。這也是名字的由來,表示多維數組在中流動。這一步指定求解器,并設定求解器的最小化目標為損失。 簡介 TensorFlow是目前最流行的深度學習框架。我們先引用一段官網對于TensorFlow的介紹,來看一下Google對于它這個產品的定位。 TensorFlow? is an open sou...
閱讀 2216·2021-09-07 09:58
閱讀 3391·2019-08-30 14:07
閱讀 1305·2019-08-29 12:32
閱讀 667·2019-08-29 11:06
閱讀 3692·2019-08-26 18:18
閱讀 3731·2019-08-26 17:35
閱讀 1381·2019-08-26 11:35
閱讀 611·2019-08-26 11:35