Я был бы радикальным. Нет BigDecimal.
Вот отличная статья
https://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Идеи отсюда.
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
testConstructors();
testEqualsAndCompare();
testArithmetic();
}
private static void testEqualsAndCompare() {
final BigDecimal zero = new BigDecimal("0.0");
final BigDecimal zerozero = new BigDecimal("0.00");
boolean zerosAreEqual = zero.equals(zerozero);
boolean zerosAreEqual2 = zerozero.equals(zero);
System.out.println("zerosAreEqual: " + zerosAreEqual + " " + zerosAreEqual2);
int zerosCompare = zero.compareTo(zerozero);
int zerosCompare2 = zerozero.compareTo(zero);
System.out.println("zerosCompare: " + zerosCompare + " " + zerosCompare2);
}
private static void testArithmetic() {
try {
BigDecimal value = new BigDecimal(1);
value = value.divide(new BigDecimal(3));
System.out.println(value);
} catch (ArithmeticException e) {
System.out.println("Failed to devide. " + e.getMessage());
}
}
private static void testConstructors() {
double doubleValue = 35.7;
BigDecimal fromDouble = new BigDecimal(doubleValue);
BigDecimal fromString = new BigDecimal("35.7");
boolean decimalsEqual = fromDouble.equals(fromString);
boolean decimalsEqual2 = fromString.equals(fromDouble);
System.out.println("From double: " + fromDouble);
System.out.println("decimalsEqual: " + decimalsEqual + " " + decimalsEqual2);
}
}
Он печатает
From double: 35.7000000000000028421709430404007434844970703125
decimalsEqual: false false
zerosAreEqual: false false
zerosCompare: 0 0
Failed to devide. Non-terminating decimal expansion; no exact representable decimal result.
Как насчет хранения BigDecimal в базе данных? Черт, это также хранит как двойное значение ??? По крайней мере, если я использую mongoDb без какой-либо расширенной конфигурации, он будет хранить BigDecimal.TEN
как 1E1
.
Возможные решения?
Я пришел с одним - используйте String для хранения BigDecimal в Java как String в базе данных. У вас есть проверка, например @NotNull
, @Min(10)
и т. Д. Затем вы можете использовать триггер при обновлении или сохранении, чтобы проверить, является ли текущая строка нужным вам числом. Там нет триггеров для монго, хотя.
Есть ли встроенный способ вызова функций запуска Mongodb?
Есть один недостаток, который мне доставляет удовольствие - BigDecimal as String в определении Swagger
Мне нужно сгенерировать чванство, поэтому наша команда разработчиков понимает, что я передаю им число, представленное в виде строки. DateTime , например, представленный в виде строки.
Есть еще одно крутое решение, которое я читал в статье выше ...
Используйте long для хранения точных чисел.
Стандартное длинное значение может хранить текущую стоимость государственного долга США (в центах, а не в долларах) 6477 раз без каких-либо переполнений. Более того: это целочисленный тип, а не с плавающей точкой. Это облегчает и точнее работать, а также гарантирует поведение.
Обновление
https://stackoverflow.com/a/27978223/4587961
Возможно, в будущем MongoDb добавит поддержку BigDecimal.
https://jira.mongodb.org/browse/SERVER-1393
3.3.8, кажется, сделал это.
Это пример второго подхода. Используйте масштабирование.
http://www.technology -ebay.de / The-команды / мобильный-де / блог / картирование-bigdecimals-с морфием-за-mongodb.html