Hur man avrundar ett tal till N decimaler i Java

1. Översikt

I den här korta artikeln ska vi titta på hur man avrundar ett tal till n decimaler i Java.

2. Decimaltal i Java

Java tillhandahåller två primitiva typer som kan användas för att lagra decimaltal: float och double . Dubbel är den typ som används som standard:

double PI = 3.1415;

Båda typerna ska dock aldrig användas för exakta värden , till exempel valutor. För det och även för avrundning kan vi använda BigDecimal- klassen.

3. Formatera ett decimaltal

Om vi ​​bara vill skriva ut ett decimaltal med n siffror efter decimaltecken kan vi helt enkelt formatera utmatningssträngen:

System.out.printf("Value with 3 digits after decimal point %.3f %n", PI); // OUTPUTS: Value with 3 digits after decimal point 3.142

Alternativt kan vi formatera värdet med klassen DecimalFormat :

DecimalFormat df = new DecimalFormat("###.###"); System.out.println(df.format(PI));

DecimalFormat tillåter oss att uttryckligen ställa in avrundningsbeteende, vilket ger mer kontroll över utdata än String.format () som används ovan.

4. Avrundning dubbel med BigDecimal

För att runda dubbla s till n decimaler kan vi skriva en hjälpmetod :

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(); }

Det finns en viktig sak att lägga märke till i den här lösningen - när du konstruerar BigDecimal ; vi måste alltid använda BigDecimal (String) konstruktör . Detta förhindrar problem med att representera inexakta värden.

Vi kan uppnå detsamma genom att använda Apache Commons Math-biblioteket:

 org.apache.commons commons-math3 3.5 

Den senaste versionen finns här.

När biblioteket har lagts till i projektet kan vi använda metoden Precision.round () , som tar två argument - värde och skala:

Precision.round(PI, 3);

Som standard använder den samma HALF_UP- avrundningsmetod som vår hjälparmetod. Därför bör resultaten vara desamma.

Observera att vi kan ändra avrundningsbeteende genom att skicka önskad avrundningsmetod som en tredje parameter.

5. Avrunda dubbel med DoubleRounder

DoubleRounder är ett verktyg i decimal4j-biblioteket. Det ger en snabb och sopfri metod för att avrunda dubbelt från 0 till 18 decimaler.

Vi kan hämta biblioteket (den senaste versionen finns här) genom att lägga till beroendet till pom.xml :

 org.decimal4j decimal4j 1.0.3 

Nu kan vi helt enkelt använda:

DoubleRounder.round(PI, 3);

Men DoubleRounder misslyckas i några scenarier, till exempel:

System.out.println(DoubleRounder.round(256.025d, 2)); // OUTPUTS: 256.02 instead of expected 256.03

6. Math.round () Metod

Ett annat sätt att avrunda siffror är att använda Math.Round () -metoden.

I det här fallet kan vi styra n antal decimaler genom att multiplicera och dela med 10 ^ n :

public static double roundAvoid(double value, int places) { double scale = Math.pow(10, places); return Math.round(value * scale) / scale; }

Denna metod rekommenderas inte eftersom den avkortar värdet . I många fall avrundas värdena felaktigt:

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

Och så listas denna metod här endast för lärande.

7. Slutsats

I denna snabba handledning täckte vi olika tekniker för att avrunda siffror till n decimaler.

Vi kan helt enkelt formatera utdata utan att ändra värdet, eller så kan vi runda variabeln med hjälp av en hjälpmetod. Vi har också täckt några bibliotek som hanterar detta problem.

Koden som användes under diskussionen finns på GitHub.