Характеристики на работа с decimal
Ако използвате типовете double или float в Java, ще забележите, че някои десетични дроби не могат да бъдат записани в тях без грешка. Това се дължи на особеностите на съхраняването на данни във формат с плаваща запетая. За да видите тази грешка, вижте този пример:
В конзолата ще пише далеч от 0.3.
В някои случаи подобна грешка може да стане критична. Например в случая, когато разглеждаме сумата от всички парични постъпления или отписвания.
Java има специален тип за точно съхраняване на десетични знаци с произволен брой десетични знаци. Това е java.math.BigDecimal. Предишният пример, използващ BigDecimal, ще изглежда така:
Сега ще видим точно 0,3, както очаквахме.
Винаги използвайте java.math.BigDecimal за съхраняване и обработка на парични суми!
Също така ви съветвам да прочетете статията за числата в Java, където са описани други класове.
Има и други полезни методи в java.math.BigDecimal освен събирането:
BigDecimal abs() - връща абсолютната стойност (премахва минуса, ако има такъв).
BigDecimal add(BigDecimal augend) е добавянето, използвано в примера.
int compareTo(BigDecimal val) - сравнение. Връща 1, ако текущата стойност е по-голяма от val, 0, ако текущата стойност е равна на val, -1, ако текущата стойност е по-малка от val.
BigDecimal divide(BigDecimal divisor, int roundingMode) - деление. Броят на десетичните знаци в върнатата стойност на this.scale(). BigDecimal divide(BigDecimal divisor, int scale, Rounding roundingMode) - деление. Връща BigDecimal, чиято стойност е this/divisor, броят на десетичните знаци е мащаб.
BigDecimalmultiply(BigDecimal multiplicand) - умножение. Връща резултата от умножението.
Това не е пълен списък с методи. Всички методи могат да бъдат прочетени в официалната документация на връзката в края на публикацията.
Имайте предвид, че някои методи приемат RoundingMode като параметър. Това е методът на закръгляване. Закръгляването е най-добре да се настрои на RoundingMode.HALF_UP, защото обикновено така се учат да закръглят в училище. Избягвайте да използвате метода на деление без опция за закръгляване, тъй като ще хвърли изключение, ако резултатът не може да бъде точно представен като краен десетичен знак.
Също така имайте предвид, че не трябва да сравнявате BigDecimal с равни. Използвайте метода compareTo за това, тъй като той правилно обработва различната точност на представянето на BigDecimal. Методът equals ще върне true само ако техните стойности и тяхната точност са равни. Тоест, за равни числата 2.0 и 2.00 не са равни.