Jeg kunne godt tænke mig en metode til at konvertere en double til en streng, som runder opad ved hjælp af halvdelen af metoden - dvs. hvis decimalen, der skal afrundes, er 5, rundes den altid opad til det næste tal. Dette er den standardmetode til afrunding, som de fleste mennesker forventer i de fleste situationer.
Jeg vil også gerne have, at der kun vises signifikante cifre - dvs. der skal ikke være nogen efterfølgende nuller.
Jeg ved, at en metode til at gøre dette er at bruge metoden String.format
:
String.format("%.5g%n", 0.912385);
returnerer:
0.91239
hvilket er fint, men den viser altid tal med 5 decimaler, selv om de ikke er signifikante:
String.format("%.5g%n", 0.912300);
returnerer:
0.91230
En anden metode er at bruge DecimalFormatter
:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
returnerer:
0.91238
Men som du kan se, bruger dette en halvjævn afrunding. Det vil sige, at den runder nedad, hvis det foregående ciffer er lige. Det, jeg gerne vil have, er dette:
0.912385 -> 0.91239
0.912300 -> 0.9123
Hvad er den bedste måde at opnå dette på i Java?
Brug setRoundingMode
, sæt RoundingMode
eksplicit til at håndtere dit problem med den halvjævne runde, og brug derefter formatmønsteret til dit ønskede output.
Eksempel:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
giver resultatet:
12
123.1235
0.23
0.1
2341234.2125
EDIT: Det oprindelige svar omhandler ikke nøjagtigheden af de dobbelte værdier. Det er fint, hvis du er ligeglad med, om den runder op eller ned. Men hvis du ønsker nøjagtig afrunding, skal du tage hensyn til værdiernes forventede nøjagtighed. Floating point-værdier har en binær repræsentation internt. Det betyder, at en værdi som 2,77395 faktisk ikke har den nøjagtige værdi internt. Den kan være lidt større eller lidt mindre. Hvis den interne værdi er lidt mindre, vil den ikke blive afrundet op til 2,7740. For at afhjælpe denne situation skal du være opmærksom på nøjagtigheden af de værdier, du arbejder med, og tilføje eller fratrække denne værdi, før du runder af. Hvis du f.eks. ved, at dine værdier er nøjagtige med op til 6 cifre, skal du føje denne nøjagtighed til værdien for at afrunde halve værdier opad:
Double d = n.doubleValue() + 1e-6;
Hvis du vil afrunde nedad, skal du trække nøjagtigheden fra.
Hvis vi antager, at value
er en double
, kan du gøre det:
(double)Math.round(value * 100000d) / 100000d
Det er for 5 cifre præcision. Antallet af nuller angiver antallet af decimaler.