Недавно я изучал вопросы вычислений с плавающей запятой в Java, запросил соответствующую информацию в Интернете, обобщил, провел некоторую сортировку и отладку и, наконец, завершил эту статью. Каждый может указать на ошибки и проблемы.
В Java переменные, объявленные с помощью float, представляют собой числа с плавающей запятой одинарной точности, а переменные, объявленные с помощью double, представляют собой числа с плавающей запятой двойной точности. Как следует из названия, объекты типа двойной точности занимают вдвое больше памяти, чем float. float — 4 байта, double — 8 байт. Данные типов float и double не могут точно отражать результаты вычислений. Это связано с тем, что float и double являются неточными вычислениями. Вы можете увидеть это через следующий код:
Скопируйте код кода следующим образом:
тест публичного класса
{
public static void main(String[] args)
{
System.out.println(0,05 + 0,01);
System.out.println(1,0 – 0,42);
System.out.println(4,015 * 100);
System.out.println(123,3/100);
}
}
Результат бега:
0.0600000000000000005
0.5800000000000001
401.49999999999994
1.23299999999999999
Чтобы получить желаемый эффект, мы можем попробовать использовать java.text.DecimalFormat для форматирования чисел с плавающей запятой:
DecimalFormat может форматировать числа в соответствии с определенным форматом. Обычно используемые символы форматирования — #, 0 и т. д. пример:
Скопируйте код кода следующим образом:
System.out.println(новый java.text.DecimalFormat("0.00").format(3.125));
System.out.println(новый java.text.DecimalFormat("0.00").format(3.135));
Но результат:
3.12
3.14
Это связано с тем, что DecimalFormat использует округление до половины (ROUND_HALF_EVEN). Проще говоря, при округлении до 5 он использует ближайшее четное число. Поэтому надежные числа с плавающей запятой невозможно получить с помощью DecimalForamt. Наконец, мы можем рассмотреть возможность использования BigDecimal для более точных вычислений:
BigDecimal предоставляет несколько конструкторов, связанных с числами с плавающей запятой:
Скопируйте код кода следующим образом:
BigDecimal(double val) Преобразует двойное число в BigDecimal.
BigDecimal(String val) Преобразует строковое представление BigDecimal в BigDecimal.
Однако использование двойных параметров для создания объектов приведет к неточным значениям. Наиболее точным является создание объектов только с помощью String.
Например:
Скопируйте код кода следующим образом:
BigDecimal bd1 = новый BigDecimal (0,05);
System.out.println(bd1.toString());
BigDecimal bd2=новый BigDecimal("0,05");
System.out.println(bd2.toString());
Получите результат:
0.05000000000000000277555756156289135105907917022705078125
0,05
Поэтому нам в конечном итоге необходимо использовать String для создания объектов, чтобы полученные результаты были максимально точными. Кроме того, если это двойное число, мы также можем использовать: BigDecimal.valueOf(double val). Причина очень проста. Исходный код JDK следующий:
Скопируйте код кода следующим образом:
общедоступное статическое значение BigDecimalOf (двойное значение)
{
вернуть новый BigDecimal(Double.toString(val));
}
Последнее, что следует отметить: сложение, вычитание, умножение и деление BigDecimal фактически в конечном итоге возвращают новый объект BigDecimal. Поскольку BigDecimal является неизменяемым, новый объект будет генерироваться во время каждой операции, поэтому .add(b); выполняется, a не сохраняет значение после операции сложения. Правильное использование должно быть a=a.add(b).