Интервьюер сошел с ума и спросил меня, почему числа с плавающей запятой неточны?

задняя часть

Многие знают, что числа с плавающей запятой в Java неточны и должны быть точно рассчитаны с помощью BigDecimal, но мало кто знает, почему числа с плавающей запятой неточны? Неточно, зачем это использовать? Эта статья положит начало волне анализа;

Мы знаем, что хранение и работа с числами в ЭВМ осуществляются в двоичном формате.Для преобразования десятичных целых чисел в двоичные целые используется метод «разделить на 2 и взять остаток и расположить в обратном порядке».

Конкретный метод:

  • Разделите десятичное целое число на 2, чтобы получить частное и остаток;
  • Разделите частное на 2 еще раз, чтобы получить частное и остаток, и так далее, пока частное не станет меньше 1.
  • Затем возьмите остаток, полученный первым, как младший значащий бит двоичного числа, а остаток, полученный позже, как старший значащий бит двоичного числа, и расположите их последовательно.

Например, мы хотим преобразовать 127 в двоичный код следующим образом:

-w624

Итак, как преобразовать десятичные десятичные числа в двоичные десятичные числа?

Десятичные десятичные числа преобразуются в двоичные десятичные числа с использованием метода «умножение на 2, округление, упорядоченное расположение».

Конкретный метод:

  • Умножьте десятичную дробь на 2, чтобы получить произведение
  • Вынуть целую часть произведения, умножить оставшуюся дробную часть на 2 и получить другое произведение
  • Затем выньте целую часть произведения и делайте это до тех пор, пока дробная часть произведения не станет равной нулю, а 0 или 1 будет последней цифрой двоичного числа. или до тех пор, пока не будет достигнута требуемая точность.

Например, попытка преобразовать 0,625 в двоичный файл:

-w624

Но 0,625 — это особый столбец, по тому же алгоритму рассчитайте двоичное значение, соответствующее 0,1:

-w624

Мы обнаружили, что в двоичном представлении 0,1 существует бесконечный цикл, то есть (0,1)10 = (0,000110011001100…)2

В этом случае у компьютера нет возможности точно представить 0,1 в двоичном виде.

Поэтому для решения проблемы невозможности точного представления некоторых десятичных знаков в двоичном виде была создана спецификация IEEE 754.

Стандарт IEEE для двоичной арифметики с плавающей запятой (IEEE 754) является наиболее широко используемым стандартом арифметики с плавающей запятой с 1980-х годов, используемым многими процессорами и операторами с плавающей запятой.

Числа с плавающей запятой и десятичные дроби не совсем одно и то же Представление десятичных дробей в компьютерах на самом деле включает в себя числа с фиксированной и плавающей запятой. Потому что в случае одного и того же количества цифр диапазон представления чисел с фиксированной запятой меньше, чем у чисел с плавающей запятой. Таким образом, в информатике числа с плавающей запятой используются для представления аппроксимаций действительных чисел.

IEEE 754 определяет четыре способа представления значений с плавающей запятой: одинарная точность (32 бита), двойная точность (64 бита), расширенная одинарная точность (более 43 бит, редко используется) и расширенная двойная точность (79 бит) выше, обычно реализуется. в 80 битах).

Чаще всего используются 32-битные числа с плавающей запятой одинарной точности и 64-битные числа с плавающей запятой двойной точности.

Числа с плавающей запятой одинарной точности занимают 4 байта (32 бита) в памяти компьютера и могут представлять широкий диапазон значений с использованием метода «плавающей запятой» (плавающей десятичной точки).

По сравнению с числами с плавающей запятой одинарной точности, числа с плавающей запятой двойной точности (double) используют 64 бита (8 байтов) для хранения числа с плавающей запятой.

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

Число с плавающей запятой a представлено двумя числами m и e: a = m × b^e.

В любой такой системе мы выбираем основание b (основание системы счисления) и точность p (то есть, сколько битов используется для хранения). m (т. е. мантисса) — это p-значное число в форме ±d.ddd...ddd (каждая цифра — это целое число от 0 до b-1 включительно).

Если первый бит m является ненулевым целым числом, m называется нормализованным. В некоторых описаниях используется бит с одним знаком (s для + или -) для обозначения положительного или отрицательного значения, поэтому m должно быть положительным. e - показатель степени.

Наконец, поскольку десятичные дроби, хранящиеся в компьютере, на самом деле являются аппроксимациями десятичных дробей, а не точными значениями, поэтому не используйте числа с плавающей запятой в своем коде для представления важных показателей, таких как суммы.

Для представления суммы рекомендуется использовать BigDecimal или Long (в центах).