摘要:浮點數并不是能夠精確表示范圍內的所有數的,雖然浮點型的范圍看上去很大。但其實浮點數在保存數字的時候做了規格化處理,以進制為例小數點前只需要保留位數對于二進制來說,小數點前保留一位,規格化后始終是節省了,這個并不需要保存。
JS 中的最大安全整數是多少?
JS 中所有的數字類型,實際存儲都是通過 8 字節 double 浮點型 表示的。浮點數并不是能夠精確表示范圍內的所有數的, 雖然 double 浮點型的范圍看上去很大: 2.23x10^(-308) ~ 1.79x10^308。 可以表示的最大整數可以很大,但能夠精確表示,使用算數運算的并沒有這么大。
它其實連這樣的簡單加法也會算錯:
console.log(0.1 + 0.2) //output: 0.30000000000000004
所以在 js 中能夠安全使用的有符號 安全 大整數(注意這里是指能夠安全使用,進行算數運算的范圍),并不像其他語言在 64 位環境中那樣是:
2^63 - 1;//9223372036854775807
而是
Math.pow(2, 53) - 1 // 9007199254740991
JS 的最大和最小安全值可以這樣獲得:
console.log(Number.MAX_SAFE_INTEGER); //9007199254740991 console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991
通過下面的例子,你會明白為什么大于這個值的運算是不安全的:
var x = 9223372036854775807; console.log(x === x + 1);// output: true console.log(9223372036854775807 + 1000); //output: 9223372036854776000
這些運算都是錯誤的結果, 因為它們進行的都是浮點數運算會丟失精度。
為什么是這個值?double 浮點數結構如下:
1 位符號位
11 位指數位
52 位尾數位
使用 52 位表示一個數的整數部分,那么最大可以精確表示的數應該是 2^52 - 1 才對, 就像 64 位表示整數時那樣: 2^63 - 1 (去掉 1 位符號位)。 但其實浮點數在保存數字的時候做了規格化處理,以 10 進制為例:
20*10^2 => 2*10^3 //小數點前只需要保留 1 位數
對于二進制來說, 小數點前保留一位, 規格化后始終是 1.***, 節省了 1 bit,這個 1 并不需要保存。
如何處理大整數Nodejs 越來越多的應用到后端的開發中, 不可避免的需要處理這樣的溢出問題, 好在已經有很多優秀的第三方庫來解決該問題:bignum、bigint。
大整數與數據庫Mysql 能處理的各個整形范圍如下
//每種類型的第二行為無符號范圍 TYPE BYTE MIN MAX TINYINT 1 -128 127 255 SMALLINT 2 -32768 32767 65535 MEDIUMINT 3 -8388608 8388607 16777215 INT 4 -2147483648 2147483647 4294967295 BIGINT 8 -9223372036854775808 9223372036854775807 18446744073709551615
BIGINT 就是 64 位整數, 一旦要處理的數據量超過了 BIGINT 能存儲的范圍,便要考慮使用字符串保存, 壞處是數字的算數運算需要通過應用程序使用大整數庫來處理,不能依賴于數據庫。
注: 常常看到 BIGINT(5) 或者 INT(10), 括號里的 5 或 10 只是表示展示寬度,并不影響數的精度范圍和存儲字節數,需要與 VARCHAR(100)或 DECIMAL(10,2)區分開
如何處理要求精度的運算?當涉及財物類型的運算時, 位數一般不會溢出, 但精度要求回更高。數據庫保存這些值時,需要使用 DECIMAL (NUMERIC 類型與之相同) 類型保存字段, 防止精度丟失。
小心位移操作前面討論了可以使用的安全整數范圍,但在做位移操作時請小心:位移操作時,會將整數截斷為 32 位有符號整型。也就是說超出這個范圍的位移操作將會得到錯誤的值。例如:
196 << 24;// 輸出: -1006632960 正確應為: 3288334336
位移的一些技巧可以戳 -> 這里
延伸閱讀代碼之謎(四)- 浮點數(從驚訝到思考)
如果你有更好的關于浮點數相關學習資料, 希望能留言推薦!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85574.html
摘要:大名鼎鼎的閉包面試必問。閉包的作用是什么。看到閉包在哪了嗎閉包到底是什么五年前,我也被這個問題困擾,于是去搜了并總結下來。關于閉包的謠言閉包會造成內存泄露錯。閉包里面的變量明明就是我們需要的變量,憑什么說是內存泄露這個謠言是如何來的因為。 本文為饑人谷講師方方原創文章,首發于 前端學習指南。 大名鼎鼎的閉包!面試必問。請用自己的話簡述 什么是「閉包」。 「閉包」的作用是什么。 首先...
摘要:類型轉換的原則占用內存字節數少值域小的類型,向占用內存字節數多值域大的類型轉換,以保證精度不降低。隱式類型轉換隱式轉換也稱為自動轉換,遵循一定的規則,由編譯器自動完成。 ...
摘要:在中,有四種方式可以讓命名進入到作用域中按優先級語言定義的命名比如或者,它們在所有作用域內都有效且優先級最高,所以在任何地方你都不能把變量命名為之類的,這樣是沒有意義的形式參數函數定義時聲明的形式參數會作為變量被至該函數的作用域內。 Scoping & Hoisting 例: var a = 1; function foo() { if (!a) { var ...
摘要:先看下這段神奇的代碼執行結果那么到底做了什么神奇的事情呢先看代碼所以這個例子其實包含了中整型類型的一個知識點。最后打印出來的值,實際上是的返回值。只有當輸入參數不在區間內,才執行代碼,基于輸入參數創建一個新的實例。 先看下這段神奇的Java代碼: public static void main(String[] args) throws Exception { doSom...
摘要:如果對應的變量中的值是個科學記數法的值,它會進行壓縮然后插入到原字符串對應的符號位置,例如按照常規轉換為如果使用它會壓縮轉換為。它取消掉了調用函數的參數,直接輸出了使用方式相同,惟一不同的是它把存放對應變量的參數可以作為數組方式傳入。 字符相關: %s - 對應的變量雙引號中的值按照原樣的內容插入到原字符串對應的%s符號位置。 %c - 參考百度百科->標準ASCII表相當于chr...
閱讀 2325·2021-11-08 13:13
閱讀 1257·2021-10-09 09:41
閱讀 1701·2021-09-02 15:40
閱讀 3196·2021-08-17 10:13
閱讀 2558·2019-08-29 16:33
閱讀 3135·2019-08-29 13:17
閱讀 3145·2019-08-29 11:00
閱讀 3306·2019-08-26 13:40