1. Общ преглед
В тази кратка статия ще разгледаме как да закръглим число до n десетични знаци в Java.
2. Десетични числа в Java
Java предоставя два примитивни типа, които могат да се използват за съхраняване на десетични числа: float и double . Double е типът, използван по подразбиране:
double PI = 3.1415;
И двата типа обаче никога не трябва да се използват за точни стойности , като валути. За това, а също и за закръгляване, можем да използваме класа BigDecimal .
3. Форматиране на десетично число
Ако просто искаме да отпечатаме десетично число с n цифри след десетичната запетая, можем просто да форматираме изходния низ:
System.out.printf("Value with 3 digits after decimal point %.3f %n", PI); // OUTPUTS: Value with 3 digits after decimal point 3.142
Като алтернатива можем да форматираме стойността с клас DecimalFormat :
DecimalFormat df = new DecimalFormat("###.###"); System.out.println(df.format(PI));
DecimalFormat ни позволява да зададем изрично поведение на закръгляване, давайки по-голям контрол на изхода, отколкото String.format (), използван по-горе.
4. Закръгляване на Double s с BigDecimal
За да закръглим двойно s до n десетични знаци, можем да напишем помощен метод :
private static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = new BigDecimal(Double.toString(value)); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); }
Има едно важно нещо, което трябва да забележите в това решение - при конструирането на BigDecimal ; винаги трябва да използваме конструктора BigDecimal (String) . Това предотвратява проблеми с представянето на неточни стойности.
Можем да постигнем същото, като използваме библиотеката Apache Commons Math:
org.apache.commons commons-math3 3.5
Най-новата версия можете да намерите тук.
След като библиотеката бъде добавена към проекта, можем да използваме метода Precision.round () , който взема два аргумента - стойност и мащаб:
Precision.round(PI, 3);
По подразбиране той използва същия метод за закръгляване HALF_UP като нашия помощен метод. Следователно резултатите трябва да са еднакви.
Имайте предвид, че можем да променим поведението на закръгляването, като предадем желания метод на закръгляне като трети параметър.
5. Закръгляване на двойки с DoubleRounder
DoubleRounder е помощна програма в библиотеката decimal4j. Той осигурява бърз и безсъдържателен метод за закръгляване на удвояване от 0 до 18 знака след десетичната запетая.
Можем да получим библиотеката (най-новата версия може да бъде намерена тук), като добавим зависимостта към pom.xml :
org.decimal4j decimal4j 1.0.3
Сега можем просто да използваме:
DoubleRounder.round(PI, 3);
Въпреки това, DoubleRounder не успее в рамките на няколко сценарии, като например:
System.out.println(DoubleRounder.round(256.025d, 2)); // OUTPUTS: 256.02 instead of expected 256.03
6. Метод Math.round ()
Друг начин за закръгляване на числата е използването на метода Math.Round ().
В този случай можем да контролираме n броя десетични знаци, като умножим и разделим с 10 ^ n :
public static double roundAvoid(double value, int places) { double scale = Math.pow(10, places); return Math.round(value * scale) / scale; }
Този метод не се препоръчва, тъй като отрязва стойността . В много случаи стойностите са закръглени неправилно:
System.out.println(roundAvoid(1000.0d, 17)); // OUTPUTS: 92.23372036854776 !! System.out.println(roundAvoid(260.775d, 2)); // OUTPUTS: 260.77 instead of expected 260.78
И така, този метод е посочен тук само за учебни цели.
7. Заключение
В този бърз урок разгледахме различни техники за закръгляване на числата до n десетични знаци.
Можем просто да форматираме изхода, без да променяме стойността, или можем да закръглим променливата с помощта на помощен метод. Обхванали сме и няколко библиотеки, които се занимават с този проблем.
Кодът, използван по време на дискусията, може да бъде намерен в GitHub.