В области внешнего интерфейса, поскольку большинство из них имеют дело с пользовательским интерфейсом, управление памятью — это часть, которую чаще всего упускают из виду. Если вы не разбираетесь в памяти, вы не сможете увидеть суть многих проблем, и вам будет сложно написать более квалифицированный код.На этот раз я перенесу вас в мир памяти.
Волшебное число JS
Случай 1: расчет и перевод суммы
18.9 * 100
=1889.9999999999998
Случай 2: нарушение математических законов
0.1 + 0.2 === 0.3
// false
(function (a, b, c) {
return a + b + c === a + ( b + c )
})(0.1, 0.2, 0.3)
// false
Случай 3: сложение в бесконечном цикле
(function (num) {
while(true) {
if (++num % 13 === 0) {
return num
}
}
})(2 ** 53)
Случай 4: JSON.parse
JSON.parse('{"a":180143985094813214124}')
//{a: 180143985094813220000}
Из приведенных выше четырех случаев мы можем видеть, что операции с числами в компьютерах часто преподносят людям некоторые «сюрпризы».Чтобы предотвратить эти неожиданные результаты, мы должны сначала понятьКак число хранится в Javascript?
хранить номера
Компьютеры хранят данные в двоичном формате, поэтому числа также необходимо преобразовать в соответствующий двоичный код:илиРазличные комбинации последовательностей.
Как преобразовать двоичный файл
Как преобразовать число в двоичное, вот пример для иллюстрации:
поставить десятичнуюпреобразовать в двоичный
При столкновении с десятичным преобразованием целая и десятичная части должны обрабатываться отдельно.Поделить напока частноедо сих пор брать каждое подразделениеполучить оставшийся результат
106 / 2 = 53 ...... 0
53 / 2 = 26 ...... 1
26 / 2 = 13 ...... 0
13 / 2 = 6 ...... 1
6 / 2 = 3 ...... 0
3 / 2 = 1 ...... 1
1 / 2 = 0 ...... 1
结果为得到的余数按照从右往左排列 1101010
десятичная дробьумножить надо тех пор, пока не останется десятичных разрядов, и посчитайте целочисленный результат после каждого умножения,
0.6953125 x 2 = 1.390625 ...... 1
0.390625 x 2 = 0.78125 ...... 0
0.78125 x 2 = 1.5625 ...... 1
0.5625 x 2 = 1.125 ...... 1
0.125 x 2 = 0.25 ...... 0
0.25 x 2 = 0.5 ...... 0
0.5 x 2 = 1 ...... 1
结果为得到的整数位按照从左往右排列 1011001
будет рассчитан Последовательности объединяются, чтобы получить преобразованный двоичный файл, выраженный в научной записи как, вычисляется двоичное число, а затем его необходимо сохранить в компьютере.В Javascript нет различия между целыми и десятичными числами.Числа равномерно хранятся в соответствии с требованиями чисел с плавающей запятой двойной точности, в основном включая следующие правила:
- использоватьСохраняет числа с плавающей запятой двойной точности
- Сохраняет данные с десятичными знаками в экспоненциальном представлении.
- Первая цифра указывает на символ послеБиты представляют экспоненту,Показатель действует согласно дополнению, то есть непосредственноДополнительная цифра
- остальнойбиты представляют мантиссу после запятой,Превосходитьчасть битаПокидатьВойти
Поскольку 11 бит бита степени не включают бит знака, для достижения эффекта положительных и отрицательных степеней введениесмещение экспоненты.
На схеме это представлено следующим образом:
Помещаем преобразованные двоичные числа в память по правилам, сначалаявляется положительным числом, поэтому бит знака должен быть,представляет положительный знак,Указывает отрицательный знак
бинарныйиндекс(Здесь необходимо добавить смещение 1023), преобразованное в двоичное как, бит экспоненты требует размещения дополнения до двух, и правило вычисления для дополнения:
- Дополнением положительного числа является само
- Дополнение отрицательного числа основано на исходном коде, знаковый бит остается неизменным, остальные биты инвертируются, и, наконец, +1 (то есть +1 на основе дополнения).
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
Таким образом, бит индекса изображения должен быть заполнен
Часть мантиссы может непосредственно заполнять двоичный код, преобразованный из десятичного
В итоге числа сохраняются в компьютере в таком виде
why 0.1 + 0.2 !== 0.3?
Поняв принцип цифрового хранения, давайте проанализируем, почему
Первое место преобразовать в двоичный
0.1 x 2 = 0.2 ...... 0
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
0.6 x 2 = 1.2 ...... 1
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
0.6 x 2 = 1.2 ...... 1
得到的整数位按照从左往右排列 000110011...
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
0.6 x 2 = 1.2 ...... 1
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
0.6 x 2 = 1.2 ...... 1
0.2 x 2 = 0.4 ...... 0
得到的整数位按照从左往右排列 001100110...
0.3 x 2 = 0.6 ...... 0
0.6 x 2 = 1.2 ...... 1
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
0.6 x 2 = 1.2 ...... 1
0.2 x 2 = 0.4 ...... 0
0.4 x 2 = 0.8 ...... 0
0.8 x 2 = 1.6 ...... 1
得到的整数位按照从左往右排列 010011001...
унифицирован в научной нотации как
Поместите его в компьютер для хранения с плавающей запятой двойной точности, и последний красный цвет представляет собой двоичный файл, который превышает мантиссу, то есть его нужно округлить на 0 до 1.
Затем после 64-битного хранения с двойной точностью двоичный файл представляется следующим образом
В настоящее времяможно увидеть сне равный
Вот так операции с числами в компьютере часто преподносят людям какие-то «сюрпризы»!
заключительные замечания
Если эта статья была вам полезна, ставьте лайк 😯
Если в тексте есть ошибки, исправьте их, если есть дополнения, оставьте сообщение.