Давайте сначала посмотрим на два вопроса:
0,1 + 0,2 == 0,3; // ЛОЖЬ
99999999999999999999 == 100000000000000000; // истинный
Первая проблема - это точность десятичных десятиц, которая обсуждалась во многих блогах отрасли. Вторая проблема заключалась в том, что в прошлом году, когда систематическая база данных исправляла данные, она обнаружила, что некоторые данные были продублированы. Эта статья начнется с нормы и суммирует вышеуказанные вопросы.
Максимальное целое число
Числа в JavaScript хранятся с использованием 64-битных номеров с плавающей запятой IEEE 754, и их формат:
SXMX 2^E.
S - бит для знака, указывающий на положительный и отрицательный. М - Мантисса, с 52 битами. E является экспонентом, с 11 битами. В спецификации ECMASCRIPT диапазон, заданный E, составляет [-1074, 971]. Таким образом, легко сделать вывод, что максимальное целое число, которое может представлять JavaScript:
1 x (2^53 - 1) x 2^971 = 1,7976931348623157e+308
Это значение number.max_value
Точно так же значение number.min_value может быть выведено как:
1 x 1 x 2^(-1074) = 5E-324
Обратите внимание, что min_value представляет положительное число, ближайшее к 0, а не наименьшее число. Наименьшее число -number.max_value
Точность десятичного десятичного
Номера JavaScript представляют собой номера с плавающей запятой с двойной режимом и хранятся в двоичном файле в компьютерах. Когда количество значительных битов превышает 52 бита, будет потеряна точность. например:
Бинарник десятичного значения 0,1 составляет 0,0 0011 0011 0011… (петля 0011)
Бинарник десятичного значения 0,2 составляет 0,0011 0011 0011… (петля 0011)
0,1 + 0,2 добавление может быть выражено как:
e = -4; m = 1.10011001100 ... 1100 (52 бита)
+ e = -3; m = 1.10011001100 ... 1100 (52 бита)
----------------------------------------------------------------------------------------------------------------------------
e = -3; m = 0,11001100110 ... 0110
+ e = -3; M = 1.10011001100 ... 1100
----------------------------------------------------------------------------------------------------------------------------
e = -3; M = 10.01100110011 ... 001
----------------------------------------------------------------------------------------------------------------------------
= 0,010011001110011 ... 001
= 0,3000000000000000004 (Десятичный)
Основываясь на вышеупомянутом расчете, мы также можем сделать вывод: когда конечное количество десятичных десятичных декораций в двоичном представлении не превышает 52 бита, его можно точно хранить в JavaScript. например:
0,05 + 0,005 == 0,055 // true
Дополнительные правила, такие как:
0,05 + 0,2 == 0,25 // true
0,05 + 0,9 == 0,95 // Неверно
Следует учитывать режимы IEEE 754, и те, кто заинтересован, могут дальше изучить его.
Точность больших целых чисел теряется
Этот вопрос редко упоминается. Во -первых, мы должны выяснить, в чем проблема:
1. Какое максимальное целое число может хранить JavaScript?
На этот вопрос был ответ ранее, и это number.max_value, очень большое число.
2. Какое максимальное целое число, которое JavaScript может хранить, не теряя точность?
Согласно SXMX 2^E, бит знака положительна, 52-разрядная мантисса полностью сочетается с 1, а показатель E-максимальное значение 971. Очевидно, что ответ все еще Number.Max_Value.
В чем именно наша проблема? Вернитесь к стартовому коду:
99999999999999999999 == 100000000000000000; // истинный
Очевидно, что 16 9 с гораздо меньше 308 10. Эта проблема не имеет ничего общего с MAX_VALUE, и она должна быть связана с Mantis M всего 52 цифр.
Это можно описать в коде:
var x = 1; // Чтобы уменьшить сумму расчета, начальное значение может быть установлено больше, например, Math.Pow (2, 53) - 10
while (x! = x+1) x ++;
// x = 9007199254740992, то есть 2^53
То есть, когда x меньше или равен 2^53, гарантируется, что точность X не потеряна. Когда x больше 2^53, точность X может быть потеряна. например:
Когда X равен 2^53 + 1, его двоичное представление:
100000000000 ... 001 (в середине 52 0s)
При хранении с двойной точностью плавучих номеров:
e = 1; m = 10000..00 (всего 52 0s, 1 - это скрытое бит)
Очевидно, это то же самое, что 2^53 хранения.
Согласно вышеуказанной идее, можно изложить, что для 2^53 + 2 его двоичный файл составляет 100000… 0010 (51 0s в середине), и его также можно хранить точно.
Правило: когда x превышает 2^53, а количество бинарных значимых цифр превышает 53 бит, будет потеряна точность. По сути, это то же самое, что и потерю точности десятичных десятиц.
Скрытый бит можно использовать для справки: учебник о двойном типе Java.
краткое содержание
Точность десятичных и больших целых чисел не только теряется в JavaScript. Строго говоря, любой язык программирования (C/C ++/C#/Java и т. Д.), Который использует формат номера с плавающей запятой IEEE 754 для хранения типов плавающей запятой имеет проблемы с потерей точности. В C# и Java предоставляются десятичные и большие классы инкапсуляции для выполнения соответствующей обработки, чтобы избежать потери точности.
Примечание: в спецификации Ecmascript уже существует десятичное предложение, но оно еще не было официально принято.
Наконец, проверьте всех:
Number.max_value + 1 == numer.max_value;
Number.max_value + 2 == numer.max_value;
...
Number.max_value + x == numer.max_value;
Number.max_value + x + 1 == Infinity;
...
Number.max_value + number.max_value == Infinity;
// вопрос:
// 1. Каково значение x?
// 2. Infinity - number.max_value == x + 1; это правда или ложь?
Вышеупомянутое краткое обсуждение потери точности десятичных декораций и крупных целых чисел в JavaScript - это все контент, которым я делюсь с вами. Я надеюсь, что вы можете дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.