Почему максимальные цифры с десятичной дробью в JavaScript только 16 - PullRequest
0 голосов
/ 21 февраля 2019

Я столкнулся с этой проблемой некоторое время назад, когда тестировал некоторые HTML-формы.Максимальное количество цифр в номере JavaScript с десятичной точкой составляет всего 16

. Я пробовал следующее

var x = 12345678912345.6789

x равно 12345678912345.68 - 16 Только цифры

var x = 123456789123.6789

x равно 123456789123.6789 - 16 Только цифры

new Number(12345678912345.6789)

12345678912345.68 - 16 Только цифры

new Number(123456789123.6789)

123456789123.6789- 16 Только цифры

если вы подсчитываете все цифры, их будет 16. Если вы увеличиваете цифры до десятичной точки, цифры после десятичной точки округляются

Аналогично

new Number(.12345678912367890)

- 0.1234567891236789 - 16 Только цифры (отсутствует конечный знак 0)

Из чего я могу сделать вывод, что я могу иметь только 16 цифр с десятичным числом вЭто.Если я попытаюсь добавить больше цифр, число начнет округляться

Я также заметил, что когда я сериализирую число с десятичной дробью в JSoN в ASP.NET MVC, он также преобразует число в максимум 16 цифр и округляетотдых

мой вопрос: почему?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Согласно спецификации JS / ECMAScript, тип Number использует плавающую точку двойной точности, которая имеет 64-битный формат (binary64), состоит из знакового бита (определяет положительное или отрицательное значение), 11 экспоненциальных бит и 52 дробных бита (каждая цифра представляет 4 бита, следовательно, 64-битный имеет 16 цифр):

Тип числа, представляющий 64-битный формат двойной точностиЗначения IEEE 754-2008 , как указано в Стандарте IEEE для двоичной арифметики с плавающей запятой.

Максимальное положительное число, которое может быть правильно представлено с использованием двойной точности, равно 9007199254740992, что может бытьдостигается с помощью Math.pow(2, 53).Если диапазон номеров находится между Math.pow(2, 53) и Math.pow(2, 54) (или между Math.pow(2, -53) и Math.pow(2, -54)), только четные числа могут быть правильно представлены, потому что экспонентные биты будут влиять на младший (младший) бит на битах дроби.

Давайте рассмотрим большую часть числа:

var x = 12345678912345.6789

var x = new Number(12345678912345.6789)

Это число содержит более 52 дробных бит (всего 72 бита), следовательно, округление используется для сохранения дробных бит до 52.

Также с этим десятичным числом:

var x = new Number(.12345678912367890)

Это число содержит 68 дробных битов, поэтому последний ноль обрезается для сохранения 64-битной длины.

Обычно числовое представлениебольше 9007199254740992 или меньше 1.1102230246251565E-16 хранятся в виде буквенных строк вместо Number.Если вам нужно вычислить очень большие числа, для выполнения арифметики произвольной точности доступны определенные внешние библиотеки.

Дополнительная информация:

ECMAScript: кодировка чисел

ECMAScript: Работа с большими целыми числами

0 голосов
/ 21 февраля 2019

В javascript Вы не можете представлять большинство десятичных дробей точно с двоичными типами с плавающей запятой (это то, что ECMAScript использует для представления значения с плавающей запятой).

Вот почему javascript использует 16 цифр после десятичной точки.например -

Попробуй запустить:

var x =  3.14159265358979323846;
print(x.toFixed(20));

и увидишь, что следующее разыгрывается для плавания.

Если ты хочешь разыграть больше 16 очков после десятичной дробиуказать, что вы можете:

  • Использовать буквальную строку для представления вашего номера
  • Использовать внешние библиотеки, такие как math.js или BigInteger.js .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...