問題描述
不久前我在測試一些 HTML 表單時遇到了這個問題.JavaScript Number 中帶小數點的最大位數僅為 16
I came across this issue a while back when I was testing some HTML forms. The Maximum number of digits in JavaScript Number with a decimal point is only 16
我已經嘗試了以下
var x = 12345678912345.6789
x 是 12345678912345.68 - 只有 16 位數字
x is 12345678912345.68 - 16 Digits only
var x = 123456789123.6789
x 是 123456789123.6789 - 只有 16 位數字
x is 123456789123.6789 - 16 Digits only
new Number(12345678912345.6789)
12345678912345.68 - 只有 16 位數字
12345678912345.68 - 16 Digits only
new Number(123456789123.6789)
123456789123.6789 - 只有 16 位數字
123456789123.6789 - 16 Digits only
如果計算總位數,則為 16.如果增加小數點前的位數,則小數點后的位數會四舍五入
if you count the total digits, they are 16. If you increase digits before decimal point, the digits after decimal point get rounded
同樣
new Number(.12345678912367890)
為 0.1234567891236789 - 僅 16 位(注意缺少尾隨 0)
is 0.1234567891236789 - 16 Digits only (notice trailing 0 is missing)
這讓我推斷我只能有 16 位數字,其中包含小數.如果我嘗試添加更多數字,則數字開始舍入
Which makes me deduce that I can only have 16 Digits in a number with Decimal in it. If I try to add more digits, the number starts to round
我還觀察到,當我在 ASP.NET MVC 中將帶小數的數字序列化為 JSoN 時,它還會將該數字轉換為 Max 16 Digits 并將其余部分四舍五入
I also observed that when I serialize a number with decimal into JSoN in ASP.NET MVC, it also converts the number to Max 16 Digits and rounds the rest
我的問題:為什么?
推薦答案
根據 JS/ECMAScript 規范,Number
type 使用 64 位格式 (binary64
) 的雙精度浮點數,由一個符號位(確定正值或負值)、11 個指數位和 52 個小數位(每個數字代表 4 位,因此 64 位有 16 位):
According to JS/ECMAScript specification, the Number
type uses double-precision floating point which has 64-bit format (binary64
), consists of a sign bit (determines positive or negative value), 11 exponent bits and 52 fraction bits (each digit represents 4-bits, hence 64-bit has 16 digits):
表示 雙精度 64 位格式 IEEE 的 Number 類型IEEE 二進制標準中指定的 754-2008 值浮點運算.
使用雙精度可以正確表示的最大正數是9007199254740992
,這可以通過使用Math.pow(2, 53)
來實現.如果數字范圍介于 Math.pow(2, 53)
和 Math.pow(2, 54)
之間(或介于 Math.pow(2, -53)
和 Math.pow(2, -54)
),只有偶數可以正確表示,因為指數位會影響小數位上的 LSB(最低有效位).
The maximum positive number which can be represented properly using double precision is 9007199254740992
, which can be achieved by using Math.pow(2, 53)
. If the number range is between Math.pow(2, 53)
and Math.pow(2, 54)
(or between Math.pow(2, -53)
and Math.pow(2, -54)
), only even numbers can be represented properly because the exponent bits will affect LSB (least-significant bit) on the fraction bits.
讓我們回顧一下大數部分:
Let's review the large number part:
var x = 12345678912345.6789
var x = new Number(12345678912345.6789)
這個數字包含超過 52 個小數位(總共 72 位),因此用于將小數位保持為 52 的舍入.
This number contains more than 52 fractional bits (72 bits in total), hence the rounding used to keep the fractional bits to 52.
還有這個十進制數:
var x = new Number(.12345678912367890)
這個數字包含 68 個小數位,因此最后一個零被切掉以保持 64 位長度.
This number contains 68 fractional bits, hence the last zero is chopped off to keep 64-bit length.
通常大于 9007199254740992
或小于 1.1102230246251565E-16
的數字表示形式存儲為文字字符串,而不是 Number
.如果您需要計算非常大的數字,可以使用某些外部庫來執行任意精度算術.
Usually numeric representation larger than 9007199254740992
or smaller than 1.1102230246251565E-16
are stored as literal strings instead of Number
. If you need to compute very large numbers, there are certain external libraries available to perform arbitrary precision arithmetic.
進一步閱讀:
ECMAScript:數字編碼
ECMAScript:處理大整數
這篇關于為什么 JavaScript 中帶小數的最大位數只有 16的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!