В приложении для финансовой или электронной коммерции существует множество расчетов денежных значений, и для этого возникает один вопрос: следует ли использовать тип данных double
или float
для представления денежных значений?
Ответ: Всегда использует java.math. BigDecimal
для представления денежных значений.
1. Двойной или плавающий?
Вот пример использования double
и float
для представления денежных значений в Java.
package com.mkyong; import java.text.DecimalFormat; public class JavaMoney { private static DecimalFormat df = new DecimalFormat("0.00"); public static void main(String[] args) { System.out.println(2.00 - 1.1); System.out.println(2.00 - 1.2); System.out.println(2.00 - 1.3); System.out.println(2.00 - 1.4); System.out.println(2.00 - 1.5); System.out.println(2.00 - 1.6); System.out.println(2.00 - 1.7); System.out.println(2.00 - 1.8); System.out.println(2.00 - 1.9); System.out.println(2.00 - 2); System.out.println("--------------------"); double i = 2.0; double j = 1.7; System.out.println("double : " + (i - j)); System.out.println("double : " + df.format(i - j)); float i2 = 2.0f; float j2 = 1.7f; System.out.println("float : " + (i2 - j2)); System.out.println("float : " + df.format(i2 - j2)); } }
Выход – Он не может точно вычислить все десятичные дроби.
0.8999999999999999 0.8 0.7 0.6000000000000001 0.5 0.3999999999999999 0.30000000000000004 0.19999999999999996 0.10000000000000009 0.0 -------------------- double : 0.30000000000000004 double : 0.30 float : 0.29999995 float : 0.30
2. Большой десятичный
Чтобы избежать описанной выше проблемы с десятичными числами, мы можем использовать BigDecimal
для представления денежных значений; кроме того, мы можем контролировать BigDecimal
масштабировать гораздо проще.
package com.mkyong; import java.math.BigDecimal; import java.math.RoundingMode; public class JavaMoney2 { public static void main(String[] args) { System.out.println("--- BigDecimal-----"); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.1))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.2))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.3))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.4))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.5))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.6))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.7))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.8))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.9))); System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(2))); System.out.println("--------------------"); BigDecimal i = BigDecimal.valueOf(2.0); BigDecimal j = BigDecimal.valueOf(1.7); System.out.println("double : " + i.subtract(j)); System.out.println("double : " + i.subtract(j).setScale(5, RoundingMode.HALF_UP)); } }
Вывод – BigDecimal
выполняет точную десятичную арифметику.
--- BigDecimal----- 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 -------------------- double : 0.3 double : 0.30000
Рекомендации
- Большой десятичный JavaDoc
- Как использовать Java BigDecimal: Учебное пособие
- Java 8 – Как суммировать большие десятичные числа с помощью потока?
Оригинал: “https://mkyong.com/java/how-do-calculate-monetary-values-in-java-double-vs-bigdecimal/”