Описание проблемы
При использовании Java для расчета номеров с плавающей запятой в проекте было обнаружено, что для таких расчетов, как 4,015*100, результат был не ожидаемый 401,5, а 401,49999999999999999999999999994. Такое длинное количество цифр недружелюбно для отображения.
Причина проблемы: представление номера с плавающей запятой
После консультации с соответствующей информацией я обнаружил, что причина в том, что номера с плавающей запятой в компьютере не могут быть полностью выражены точно. Например, для двойного типа 38414.4, компьютер хранит его так:
Конвертировать в двоичный файл: 100101100001110.0110011001100110011001100110011001100110000
Преобразовать в предмет
Метод подсчета обучения: 1.001011000011100110011001100110011001100110011001100110011001100110000 × 2^15
Формат двойного кодирования выглядит следующим образом:
Двойной бит бита 1 цифр кода 11 цифр Mantissa 52 цифр
Бит символа: положительное число - 0
Код заказа: 15 является положительным числом, поэтому самый высокий бит составляет 1, самый низкий бит - минус 1, который составляет 10000001110
Mantissue: удалите по умолчанию 1 самый высокий бит, который 0010110000111001100110011001100110011001100110011001100000000000000
В совокупности окончательное кодирование: 0 1000001110 00101100001110011001100110011001100110011001100110011001100110000000000
Отсюда мы видим, что основная причина заключается в том, что бинарное кодирование делает дробную часть невозможной, чтобы полностью выразить, например, 0,4 = 0,25 + 0,125 + ..., что может быть только бесконечно близко. Следовательно, ошибки точности возникнут при расчете номеров с плавающей запятой.
Решение: высокая точность
BigDecimal в Java может поддерживать операции с плавающей запятой с произвольной точностью. В книге «Эффективная Java» рекомендуется, чтобы Float и Double использовались для научных расчетов или инженерных расчетов, в то время как java.math.bigdecimal используется в коммерческих расчетах.
Существует много методов строительства для BigDecimal, таких как BigDecimal (Double) и BigDecimal (String). Следует отметить, что параметры конструкции являются типом строки, чтобы убедиться, что точность не теряется, поскольку сам двойной тип является не полностью точным. Следовательно, это должно быть написано следующим образом: BigDecimal («0,02»).
Основные операции двойного типа можно найти в BigDecimal. Кроме того, BigDecimal также может использоваться для форматирования вывода с помощью NumberFormat.
BigDecimal генерирует новые BigDecimal объекты при выполнении операций, поэтому он принесет больше накладных расходов на производительность по сравнению с двойным.
Предварительное исследование о высокой реализации
Итак, как BigDecimal может представлять произвольную точность? Вот только предварительный анализ.
Во -первых, давайте посмотрим на реализацию Biginteger. Обычный тип Int составляет 32 бита, поэтому существует ограничение диапазона. Biginteger имеет переменную члена int [] Mag, так что более длинный массив Int позволяет представлять целые числа любого размера.
Давайте посмотрим на реализацию BigDecimal. В его официальном введении говорится, что любой BigDecimal может быть представлен как unscaledValue × 10^-Scale. UnscaledValue является целым числом любого размера, соответствующего переменной элемента BigInteger Intval в исходном коде; Шкала - это порядок, соответствующий переменной шкале Int в исходном коде. Таким образом, BigDecimal реализуется на основе BigInteger.
Вышеуказанное решение проблемы точности с плавающей запятой в Java, введенной вам редактором. Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение.