
Σκέφτομαι να γράφει δύο περιορισμένες εναλλακτικές λύσεις για την ακρίβεια να BigDecimal, δηλαδή DecimalInt και DecimalLong. Αυτές θα είναι σε θέση να αντιμετωπίσουν με αριθμούς μέσα τα πραγματικά όρια της int και καιρό με έναν αυθαίρετο αριθμό των δεκαδικών ψηφίων, creatable τόσο ευμετάβλητος και αμετάβλητος μορφή. Το σχέδιό μου είναι να κάνουμε την υποστήριξη DecimalInt +/- 999.999.999 σε +/- 0,999999999 και DecimalLong το ίδιο, αλλά με έως και 18 ψηφία.


Αυτό θα γίνει με τη διατήρηση ενός δεκαδικού ψηφίου τιμή μέτρησης του 0-9 για DecimalInt και 0-18 για DecimalLong κατά μήκος της πλευράς η πραγματική τιμή που είναι αποθηκευμένη ως κλίμακα int ή μεγάλο. Η κανονική χρήση θα είναι για μικρό αριθμό των δεκαδικών ψηφίων, όπως για τις τιμές χρήματα και το απόθεμα, συνήθως 2-4 δεκαδικά ψηφία.


Οι βασικές απαιτήσεις είναι (α) άπαχο αποτύπωμα (2 τάξεις, καθώς OverflowException), και (β) την πλήρη υποστήριξη όλων των βασικών λειτουργιών καθώς και όλα τα μαθηματικά που έχει νόημα.


Googling για τα αποτελέσματα δεν επέστρεψε κανένα προφανή επιτυχίες - που όλα φαίνονταν να αφορούν αυθαίρετες δεκαδικά ψηφία.


Οι ερωτήσεις μου είναι: Έχει αυτό έχει ήδη γίνει; Τα κρυμμένα υπάρχουν λεπτές αποχρώσεις σε αυτό και γι 'αυτό δεν έχει ήδη γίνει; Έχει κανείς ακούσει φήμες για Java υποστηρίζει ένα δεκαδικό τύπου, όπως DotNet του.


EDIT: Αυτό είναι διαφορετικό από BigDecimal, γιατί θα πρέπει να είναι (α) μια κόλαση πολύ πιο αποτελεσματικό να μην ασχοληθεί με μια σειρά από ints, και (β) δεν θα ολοκληρωθεί BigInteger έτσι θα είναι πιο λιτή στη μνήμη πάρα πολύ, και (γ) θα έχει μεταβλητό επιλογή έτσι θα είναι πιο γρήγορα εκεί. Εν ολίγοις - λιγότερη επιβάρυνση για τις απλές περιπτώσεις χρήσης όπως «θέλω να αποθηκεύσετε μια ισορροπία τράπεζας χωρίς την επιβάρυνση των BigDecimal και την ανακρίβεια των διπλών».


EDIT: Έχω την πρόθεση να κάνει όλα τα μαθηματικά χρησιμοποιώντας int ή πολύ για να αποφύγει το κλασικό πρόβλημα της: 1.586,60 - 708,75 = 877.8499999999999 αντί για 877,85

 
Ελαφρύ δεκαδικό κατηγορίας Java
===============================



Υποψιάζομαι έντονα ο λόγος για τον οποίο δεν έχει γίνει είναι ότι η επιβάρυνση των BigDecimal και BigInteger δεν είναι τόσο καλή όσο νομίζετε, και την αποφυγή δεν αξίζει τον κόπο και τον κίνδυνο του να πάρει λάθος με κάποιο διακριτικό τρόπο.


Για να χρησιμοποιήσετε το παράδειγμά σας: για κάθε οικονομικό εφαρμογή, εξοικονομώντας μερικές δεκάδες bytes είναι ένα μη-ζήτημα και περιορισμένη ακρίβεια μια συμφωνία-διακόπτης (οι τιμές των μετοχών μου έχουν συνήθως 2-4 ψηφία στις ΗΠΑ, αλλά αν θέλετε να ασχοληθεί με τις αναδυόμενες αγορές , θα συναντήσετε τα νομίσματα με ανεξέλεγκτο πληθωρισμό, όπου ένα 15-ψήφιο ποσό που αγοράζει μισό καρβέλι ψωμί).


Βασικά, αυτό ακούγεται σαν απλά μια άλλη περίπτωση πρόωρης βελτιστοποίησης.

 

Οι περισσότεροι άνθρωποι που είναι ιδιαίτερα ανησυχούν για στρογγυλοποίηση σφάλματα χρήση BigDecimal και BigInteger που αποδίδει αρκετά καλά στις περισσότερες περιπτώσεις. 


Ωστόσο, όταν η απόδοση είναι πιο κρίσιμη, χρησιμοποιώντας διπλά με στρογγυλοποίηση κάνει τη δουλειά του. Αυτό είναι συχνά ξεχασμένο από αρχάριους, αλλά δεν μπορείτε απλά να πάρουν ένα διπλό αποτέλεσμα χωρίς λογική γύρο και περιμένετε να πάρετε μια λογική απάντηση.


Στη συντριπτική πλειοψηφία των περιπτώσεων διπλασιάζεται με στρογγυλοποίηση είναι όλα όσα χρειάζεται.



```
System.out.printf("%.2f%n", 1586.60-708.75);

```

εκτυπώσεις



```
877.85

```
 

Αν ψάχνετε σε ένα σταθερό, μικρό αριθμό των δεκαδικών ψηφίων για τη διαχείριση των χρημάτων, τότε αυτό γίνεται συνήθως κρατώντας ακέραιο (μεγάλη, αν είναι απαραίτητο) τον αριθμό των λεπτών, ή εκατοστά του σεντ. 


Αν έχετε να κάνετε με τα χρήματα, τότε θα πρέπει να είμαστε προσεκτικοί για το πώς θα χειριστεί στρογγυλοποίηση. Αν οι υπολογισμοί σας θα πρέπει να ελέγχονται υπάρχουν κανόνες για το πώς αυτό το είδος του πράγματος γίνεται. Επίσης υποθέτω ότι γνωρίζετε ότι ορισμένες επιχειρήσεις δεν μπορεί να γίνει με ακρίβεια (τμήμα είναι το προφανές παράδειγμα).

 

Εάν η εστίασή σας είναι για φορητές συσκευές δούμε [Ρεάλ](http://real-java.sourceforge.net/Real.html) . Ρεάλ επιτρέπει την [ακρίβεια](http://real-java.sourceforge.net/javadoc/index.html) του αριθμού που πρόκειται να ρυθμιστεί από 0 έως 16. Είναι σχεδιασμένο για κινητά τηλέφωνα MIDP. 


Επίσης ενδιαφέρον, να δούμε την [εποικοδομητική ρεάλια](http://www.hpl.hp.com/personal/Hans_Boehm/new_crcalc/CRCalc.html) βιβλιοθήκη. Δεν είναι ελαφρύ όμως.


Αναφορικά με το παρακάτω σχόλιο, μπορείτε να μην χρησιμοποιήσετε το [Apache Commons Math βιβλιοθήκη](http://commons.apache.org/math/userguide/fraction.html) για την εργασία με κλάσματα; Υπάρχει κάποιος λόγος που δεν θα εργάζονται εκεί;

 

Μου φαίνεται ότι αν θέλετε αυθαίρετη ακρίβεια τότε θα έχετε την ευκαιρία να χρειάζονται ένα απροσδιόριστο αριθμό των bits να εκπροσωπεί το δεκαδικό. Αυτό σημαίνει ότι κάποιο είδος της στρατηγικής κατανομής σειρά θα είναι απαραίτητη για την δεκαδικό. Θα μπορούσατε να σκάφος το δικό σας εδώ, αλλά BigInteger κάνει αρκετά αποτελεσματικά και λειτουργεί


Θα πρέπει να καθορίσετε ποιο είναι το μικρότερο (μη μηδενική) τιμή θα πρέπει να εκπροσωπεί είναι. Αυτό θα είναι 10 ^ - (2 ^ n), όπου n + 1 είναι ο αριθμός των bits που χορηγεί στην εκθέτη. Με BigDecimal αυτό είναι 10 ^ - (2 ^ 31). Θα μπορούσατε να χρησιμοποιήσετε ένα αυθαίρετο εκθέτη μέγεθος, αλλά η σειρά θα πρέπει να είναι αρκετό για κανέναν.


Έτσι, αυτό που χρειάζεστε είναι μια απεριόριστη ακέραιος δεκαδικό για να σας δώσει την αυθαίρετη ακρίβεια, και ένα σταθερό εκθέτη μέγεθος, ανάλογα με το τι θέλετε ελάχιστη αναπαρασταθεί αξία σας να είναι. Ουσιαστικά αυτό είναι BigDecimal? η μόνη αλλαγή είναι ότι θα χρησιμοποιήσετε κάποιο μικρότερο αντικείμενο και όχι το int χρησιμοποιείται από BigDecimal. Θα ήθελα να αμφιβάλλω κατά πόσο η εξοικονόμηση χώρου είναι αξίζει τον κόπο. Θα ήθελα να πιστεύω ότι BigDecimal πρόκειται να κάνει ό, τι χρειάζεστε με μόλις οποιαδήποτε περισσότερο η χρήση της μνήμης από οποιαδήποτε λύση που θα δημιουργήσει τον εαυτό σας.


Φυσικά, θα μπορούσατε να επιλέξετε ένα μέγιστο αριθμό σημαντικών ψηφίων που θα χρειαστείτε? τότε θα πρέπει αποθήκευσης σταθερό μέγεθος για δύο δεκαδικό και εκθέτη, και αυτό είναι ένα πάρα πολύ λιγότερο αποθήκευσης. Απλά χρησιμοποιήστε ένα σταθερό αριθμό λαχταρά ως δεκαδικό.

 