Αυτό που θα ήθελα είναι μια μέθοδος για τη μετατροπή ενός double σε συμβολοσειρά που στρογγυλοποιεί με τη μέθοδο half-up - δηλαδή αν το δεκαδικό που πρέπει να στρογγυλοποιηθεί είναι 5, πάντα στρογγυλοποιεί στον επόμενο αριθμό. Αυτή είναι η τυπική μέθοδος στρογγυλοποίησης που περιμένουν οι περισσότεροι άνθρωποι στις περισσότερες περιπτώσεις.
Θα ήθελα επίσης να εμφανίζονται μόνο τα σημαντικά ψηφία - δηλαδή δεν θα πρέπει να υπάρχουν μηδενικά στο τέλος.
Γνωρίζω ότι μια μέθοδος για να γίνει αυτό είναι η χρήση της μεθόδου String.format
:
String.format("%.5g%n", 0.912385);
επιστρέφει:
0.91239
το οποίο είναι υπέροχο, ωστόσο εμφανίζει πάντα αριθμούς με 5 δεκαδικά ψηφία, ακόμη και αν δεν είναι σημαντικοί:
String.format("%.5g%n", 0.912300);
επιστρέφει:
0.91230
Μια άλλη μέθοδος είναι η χρήση του DecimalFormatter
:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
επιστρέφει:
0.91238
Ωστόσο, όπως μπορείτε να δείτε, αυτό χρησιμοποιεί στρογγυλοποίηση μισού ζυγού. Δηλαδή θα στρογγυλοποιήσει προς τα κάτω εάν το προηγούμενο ψηφίο είναι ζυγό. Αυτό που θα ήθελα είναι το εξής:
0.912385 -> 0.91239
0.912300 -> 0.9123
Ποιος είναι ο καλύτερος τρόπος για να επιτευχθεί αυτό στη Java;
Χρησιμοποιήστε το setRoundingMode
, ορίστε ρητά το RoundingMode
για να χειριστείτε το πρόβλημά σας με τον μισό-ζυγό γύρο, και στη συνέχεια χρησιμοποιήστε το πρότυπο μορφοποίησης για την απαιτούμενη έξοδο.
Παράδειγμα:
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));
}
δίνει την έξοδο:
12
123.1235
0.23
0.1
2341234.2125
EDIT: Η αρχική απάντηση δεν ασχολείται με την ακρίβεια των διπλών τιμών. Αυτό είναι μια χαρά αν δεν σας ενδιαφέρει πολύ αν στρογγυλοποιεί προς τα πάνω ή προς τα κάτω. Αλλά αν θέλετε ακριβή στρογγυλοποίηση, τότε πρέπει να λάβετε υπόψη την αναμενόμενη ακρίβεια των τιμών. Οι τιμές κινητής υποδιαστολής έχουν δυαδική αναπαράσταση εσωτερικά. Αυτό σημαίνει ότι μια τιμή όπως το 2,77395 δεν έχει στην πραγματικότητα αυτή την ακριβή τιμή εσωτερικά. Μπορεί να είναι ελαφρώς μεγαλύτερη ή ελαφρώς μικρότερη. Εάν η εσωτερική τιμή είναι ελαφρώς μικρότερη, τότε δεν θα στρογγυλοποιηθεί σε 2,7740. Για να διορθώσετε αυτή την κατάσταση, πρέπει να έχετε επίγνωση της ακρίβειας των τιμών με τις οποίες εργάζεστε και να προσθέτετε ή να αφαιρείτε αυτή την τιμή πριν από τη στρογγυλοποίηση. Για παράδειγμα, όταν γνωρίζετε ότι οι τιμές σας είναι ακριβείς μέχρι 6 ψηφία, τότε για να στρογγυλοποιήσετε τις μισές τιμές προς τα πάνω, προσθέστε αυτή την ακρίβεια στην τιμή:
Double d = n.doubleValue() + 1e-6;
Για να στρογγυλοποιήσετε προς τα κάτω, αφαιρέστε την ακρίβεια.
Υποθέτοντας ότι το value
είναι ένα double
, μπορείτε να κάνετε:
(double)Math.round(value * 100000d) / 100000d
Αυτό είναι για ακρίβεια 5 ψηφίων. Ο αριθμός των μηδενικών υποδηλώνει τον αριθμό των δεκαδικών ψηφίων.
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;