View Full Version : [JAVA] Arrotondamento double non convincente
franksisca
12-07-2011, 17:18
private double arrotondaDoubleEccesso(double d, int cifre) {
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(cifre, BigDecimal.ROUND_UP);
return bd.doubleValue();
}
sappiamo bene come funziona, però io ho fatto esattamente questa operazione:
25/45
10/45
10/45
e i risultati sono stati
0.556
0.223
0.223
che ovviamente fà 1.002
posso ovviare in qualche modo a questo problema o no?
banryu79
12-07-2011, 21:58
posso ovviare in qualche modo a questo problema o no?
Se prima di fare la somma arrotondi tutti i parziali alla terza cifra con ROUND_UP ovviamente il totale calcolato non è equivalente a quello dato dai valori originari.
Il "rimedio" è uno solo: evitare di arrotondare i parziali prima di sommarli.
Immagino tu voglia arrivare ad avere la somma totale esatta in uno scenario in cui per qualche ragione sei costretto a elaborare così i parziali prima di poterli sommare, ma senza una descrizione più articolata del tuo scenario, limiti da rispettare e requisiti da soddisfare è molto difficile darti qualche consiglio.
Tirando un tentativo a caso potrei allora suggerirti di non salvare il valore double arrotondato della frazione 10/45, ma la frazione stessa magari usando due short o due int (volendo potresti sempre prima minimizzare i termini della frazione, ad es.: 10/45 -> 2/9) fino al momento in cui dovrai fare la somma: a quel punto produci il valore double del risultato di ogni frazione da sommare e lo accumuli alla somma.
Quoto banryu, se hai bisogno dell'arrotondamento, lo devi effettuare alla fine dei calcoli, non durante gli stessi.
franksisca
13-07-2011, 09:47
allora il problema in esame è quello del calcolo delle tabelle millesimali, quindi i valori "parziali" mi servono, perchè devo assegnare dei millesimi ad ogni singola unità immobiliare.
l'idea della frazione quindi non è adattabile, così come non è adattabile un troncamento forzato a tre cifre. Dovrò vedere se sesistono costanti diverse da ROUND_UP che mi possono aiutare.
franksisca
13-07-2011, 10:07
al momento la soluzione più immediata (e anche la più ovvia) è di usare BigDecimal.ROUND_HALF_EVEN. Se comunque avete anche altre idde postate pure :D
Non potresti usare sempre i valori "effettivi", salvati come BigDecimal (quindi a precisione infinita) e convertirli solo quando li devi rappresentare, cioè praticamente quando li devi stampare? Dovresti costruirti una funzione che traduce il numero in stringa, senza passare per .doubleValue().
franksisca
13-07-2011, 20:41
Non potresti usare sempre i valori "effettivi", salvati come BigDecimal (quindi a precisione infinita) e convertirli solo quando li devi rappresentare, cioè praticamente quando li devi stampare? Dovresti costruirti una funzione che traduce il numero in stringa, senza passare per .doubleValue().
forse il problema non è chiaro.
io ho bisogno della rappresentazione con 3 cifre dopo la virgola dal momento del calcolo perchè devono essere immediatamente visualizzati.
banryu79
14-07-2011, 08:01
forse il problema non è chiaro.
io ho bisogno della rappresentazione con 3 cifre dopo la virgola dal momento del calcolo perchè devono essere immediatamente visualizzati.
Ieri mi era venuto in mente di suggerirti ti farti una funzione, usare un array per memorizzare i parziali, e arrotondare per eccesso o per difetto ogni elemento in base all'indice (pari o dispari) e comunque avendo cura di verificare la somma totale. Ma non so se è una buona idea o meno: non mi sono mai trovato in un caso simile al tuo.
franksisca
17-07-2011, 15:38
Ieri mi era venuto in mente di suggerirti ti farti una funzione, usare un array per memorizzare i parziali, e arrotondare per eccesso o per difetto ogni elemento in base all'indice (pari o dispari) e comunque avendo cura di verificare la somma totale. Ma non so se è una buona idea o meno: non mi sono mai trovato in un caso simile al tuo.
valuterò
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.