В приложении для финансовой или электронной коммерции существует множество расчетов денежных значений, и для этого возникает один вопрос: следует ли использовать тип данных 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/”