предисловие
Когда вы идете на собеседование в компанию, работающую в сфере интернет-финансов или электронной коммерции, вы обычно сталкиваетесь с чем-то вроде «равный? «Этот вопрос — хорошее предложение для фронтенд-людей, не имеющих академического образования. Некоторые люди знают, чтоне равно, но если вы продолжите спрашивать почему, вы не сможете внятно ответить.
В этой колонке собраны ответыне равноидея, прежде чем ответитьпроцесс расчета.
Процесс расчета 0,1+0,2Процесс расчета
1. Преобразование десятичного числа в двоичное
Все вычисления внутри JS выполняются в бинарном виде.так операцияпервыйа такжеПреобразование из десятичной в двоичную.
-
Алгоритм преобразования 0.1 в двоичный код:
0,1*2=0,2====== Вынуть целую часть 0
0,2*2=0,4====== Вынуть целую часть 0
0,4*2=0,8====== Вынуть целую часть 0
0,8*2=1,6====== Вынуть целую часть 1
0,6*2=1,2====== Вынуть целую часть 1
Это будет бесконечно повторяться
0,2*2=0,4====== Вынуть целую часть 0
0,4*2=0,8====== Вынуть целую часть 0
0,8*2=1,6====== Вынуть целую часть 1
0,6*2=1,2====== Вынуть целую часть 1
Таким образом, преобразование 0,1 в двоичное число: 0,0001 1001 1001 1001...
-
Алгоритм конвертации 0.2 в бинарник:
0,2*2=0,4====== Вынуть целую часть 0
0,4*2=0,8====== Вынуть целую часть 0
0,8*2=1,6====== Вынуть целую часть 1
0,6*2=1,2====== Вынуть целую часть 1
Это будет бесконечно повторяться
0,2*2=0,4====== Вынуть целую часть 0
0,4*2=0,8====== Вынуть целую часть 0
0,8*2=1,6====== Вынуть целую часть 1
0,6*2=1,2====== Вынуть целую часть 1
Таким образом, 0,2, преобразованное в двоичное число, равно: 0,0011 0011 0011 0011...
Обратите внимание здесьа такжеПреобразованный двоичный файл бесконечен. Кроме тогоВ современных браузерах для хранения бинарника используется бинарник в виде чисел с плавающей запятой, поэтому необходимо преобразовать бинарник, преобразованный выше, в бинарник в виде чисел с плавающей запятой.
2. Преобразование в число с плавающей запятой
Числа с плавающей запятой делятся на числа одинарной точности, соответствующие 32-разрядным операционным системам, и числа двойной точности, соответствующие 64-разрядным операционным системам. Большинство современных операционных систем являются 64-разрядными операционными системами, поэтому здесь я только объясню, как преобразовать двоичный файл в двоичный файл с плавающей запятой двойной точности.
В числах с плавающей запятой двойной точности используется 1 бит для представления бита знака, 11 бит для представления бита экспоненты и 52 бита для представления десятичного бита, как показано на следующем рисунке:
-
Бит знака: 0 для положительных чисел, 1 для отрицательных чисел;
-
Биты экспоненты:
阶数+偏移量Заказ:,- количество цифр кода заказа. Смещение заключается в перемещении десятичной точки только в целые числаКоличество цифр для перемещения, когда время, положительное число означает перемещение влево, отрицательное число означает перемещение вправо; -
Десятичный разряд: число после двоичной точки.
Следующий поставитьпреобразован в двоичныйПреобразование в двоичный формат с плавающей запятой.
-
Сначала переместите десятичную точку только в целое число, чтобы переместиться на 4 бита вправо, поэтому смещение равно, по формуле вычисления числа показателей,Пучокпреобразовать в двоичный, если не хватает 11 бит, его нужно заполнить нулями, и, наконец, количество степеней;
-
десятичные разряды, так как можно зарезервировать только 52 десятичных знака, 53-я цифра равна 1, поэтому 1 увеличивается.
Результат преобразования показан на следующем рисунке:
Аналогично, положитьпреобразован в двоичныйПреобразованный в двоичный формат в виде чисел с плавающей запятой, результат преобразования показан на следующем рисунке:
Сложение с плавающей запятой
При добавлении чисел с плавающей запятой необходимо сравнить, соответствует ли количество показателей степени.Если они совпадают, десятичные разряды добавляются напрямую.Если они несовместимы, число показателей степени должно число показателей должно быть скорректировано от меньшего к большему.
Для удобства записи число с плавающей запятой, преобразованное из 0,1, называется 0,1, а число с плавающей запятой, преобразованное из 0,2, называется 0,2.
Бит экспоненты 0,1 равен, бит экспоненты 0,2 равен. Следовательно, чтобы добавить 1 к биту экспоненты 0,1, то есть сдвинуть десятичную точку 0,1 влево на 1 бит и зафиксировать целочисленный бит числа с плавающей запятой на 1. Процесс выглядит следующим образом
1.1001100110011001100110011001100110011001100110011010 原先
0.11001100110011001100110011001100110011001100110011010 移动后
0.1100110011001100110011001100110011001100110011001101 将小数的第53位舍去,因为为0故不需进1
в результате чего десятичные разряды 0,1 становятся следующими:
Теперь, когда показатели степени 0,1 и 0,2 одинаковы, добавьте десятичные дроби напрямую.
1100110011001100110011001100110011001100110011001101 0.1的小数位
+ 1001100110011001100110011001100110011001100110011010 0.2的小数位
= 10110011001100110011001100110011001100110011001100111
Вы обнаружите, что теперь есть еще один десятичный знак, превышающий 52 цифры, поэтому последняя цифра десятичного разряда должна быть усечена, а последняя цифра десятичного разряда равна 1, поэтому 1 следует добавить, как показано ниже:
10110011001100110011001100110011001100110011001100111
1011001100110011001100110011001100110011001100110100
Усечение последней цифры десятичного разряда эквивалентно смещению запятой на один разряд влево, поэтому показатель степени должен быть увеличен на 1, а показатель степени в это время равен показателю 0,2., после добавления 1 становится, преобразованный в двоичный как, Тогда число с плавающей запятой после сложения будет следующим:
Преобразование числа с плавающей запятой в десятичное
После того, как вычисление двоичного числа с плавающей запятой завершено, результат (двоичное число с плавающей запятой) преобразуется в десятичное, и формула преобразования, s — бит знака равен 0 или 1, e — значение бита экспоненты с плавающей запятой, преобразованное в десятичное число, i — количество десятичных разрядов слева направо, первая цифра,Указывает, что каждый бит имеет значение 0 или 1.
Затем преобразуйте двоичное число с плавающей запятой в десятичное по формуле:
Результат выглядит следующим образом:
Из-за проблем с точностью только.
Отвечать
не равно,Потому чтоПри вычислении произошло две потери точности. первый раз ва такжеПри преобразовании в двоичное число с плавающей запятой двойной точности, поскольку десятичный разряд двоичного числа с плавающей запятой может хранить только 52 бита, 53-я цифра после запятой должна быть 1, затем 1 и 0 отбрасываются, что приводит к потеря точности... второй раз ва такжеПосле преобразования в двоичные числа с плавающей запятой в процессе сложения двоичных чисел с плавающей запятой добавление десятичных разрядов приводит к еще одному десятичному разряду, причем 53-я цифра должна быть 1, затем добавляется 1 и отбрасывается 0. , вызывая еще одну потерю точности. в конечном итоге привести кне равно.
расширять
Если вы ответите, интервьюер может продолжить спрашивать вас: "не равноЭто вызовет эти ошибки? "
Вы можете ответить так: «Ошибка, из-за которой страница статистики будет отображаться беспорядочно, аскидкаПосле юаней сумма платежа недостаточнаЮань и другие подобные баги. "
Вы также можете продолжать спрашивать: «Как решитьне равноЭта проблема".
Ответ: "Это можно решить с помощью математической библиотеки Math.js или с помощьюtoFixed()округлить результат расчета, ноtoFixed()Существуют также ошибки точности округления в Chrome или Firefox. Можно использоватьMath.roundЧтобы решить ошибку точности, например, положитьокругление зарезервированодесятичные разряды, поставить первымполучать, затем используйтеMath.roundОкругление, получите, затем поставьтеполучать, что косвенно обеспечивает округление. Можно использоватьMath.powсделать простой пакетMath.round(Math.pow(10, m) * number) / Math.pow(10, m),вnumberэто число, которое нужно округлить,mзаключается в том, чтобы сохранить несколько знаков после запятой.