È possibile stabilire, anche approssimativamente, quale sarebbe la massima perdita di precisione quando si gestiscono due valori double
in java (aggiunta/sottrazione)? Probabilmente lo scenario peggiore è quando due numeri non possono essere rappresentati esattamente, e quindi viene eseguita un'operazione su di essi, che si traduce in un valore che non può essere rappresentato anche esattamente.Java: massima perdita di precisione in una doppia aggiunta/sottrazione
risposta
Dai un'occhiata allo Math.ulp(double)
. Il ulp di un double
è il delta al successivo valore più alto. Ad esempio, se si aggiungono numeri e uno è inferiore all'ulp dell'altro, si sa che l'aggiunta non avrà alcun effetto. Se si moltiplicano due doppi, è possibile moltiplicare le loro ulp per ottenere l'errore massimo del risultato.
Questo è esattamente quello che volevo – Bober02
Il caso peggiore è che tutta la precisione può essere persa. Questo può accadere ad esempio se il risultato è maggiore del numero finito rappresentabile più grande. Quindi verrà memorizzato come POSITIVE_INFINITY (o NEGATIVE_INFINITY).
Per quanto riguarda l'aggiornamento, può succedere con l'aggiunta.
double a = Double.MAX_VALUE;
System.out.println(a);
double b = a + a;
System.out.println(b);
Risultato:
1.7976931348623157E308
Infinity
Vedi on-line: ideone
In generale, la dimensione dell'errore rappresentazione è relativo alla dimensione dei vostri numeri.
Vedere le modifiche sopra - Intendevo principalmente aggiunta ... – Bober02
Si potrebbe avere uno sguardo alla effettiva precisione dei vostri input, ad esempio il codice qui sotto uscite:
input: 0.01000000000000000020816681711721685132943093776702880859375
range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875]
range size: 3.4694469519536141888238489627838134765625E-18
input: 10000000000000000
range: [9999999999999998 - 10000000000000002]
range size: 4
public static void main(String[] args) {
printRange(0.01);
printRange(10000000000000000d);
}
private static void printRange(double d) {
long dBits = Double.doubleToLongBits(d);
double dNext = Double.longBitsToDouble(dBits + 1);
double dPrevious = Double.longBitsToDouble(dBits + -1);
System.out.println("input: " + new BigDecimal(d));
System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]");
System.out.println("range size: " + new BigDecimal(dNext - dPrevious));
}
Si avrebbe ancora bisogno di poi stimare la perdita sul risultato della vostra operazione. E questo non funziona con i casi d'angolo (attorno a Infinity, NaN ecc.).
- 1. C# da doppia a decimale perdita di precisione
- 2. Java calcolo doppia perdere in precisione
- 3. Astyanax Cassandra Precisione doppia precisione
- 4. Java doppia precisione costante moltiplicazione/divisione
- 5. Formato doppia precisione in PostgreSQL
- 6. C# Alta precisione doppia
- 7. estesa doppia precisione
- 8. 'sprintf': precisione doppia in C
- 9. possibile perdita di errore di precisione in java
- 10. doppia sottrazione questione di precisione
- 11. Perdita di precisione con doppio C++
- 12. Massima precisione sotto illimitata?
- 13. Sospensione: Trovato: float, previsto: doppia precisione
- 14. SSE2: Doppia funzione di log precisione
- 15. Quanto è grande la conversione della perdita di precisione da lunga a doppia?
- 16. Miglior algoritmo per evitare perdita di precisione?
- 17. JavaScript ha una precisione del numero a virgola mobile doppia?
- 18. WebAPI, JSON.Net e perdita della precisione decimale
- 19. C++ perdita di precisione in virgola mobile: 3015/0.00025298219406977296
- 20. Qual è la massima precisione dell'opacità CSS3?
- 21. Stringa di formattazione in scala - massima precisione decimale
- 22. come dividere piccoli numeri di doppia precisione correttamente senza errori di precisione?
- 23. Precisione del timer in java
- 24. il modo migliore per generare una doppia precisione completa in un file di testo
- 25. Come utilizzare Java String.format con una precisione variabile?
- 26. Perdita di precisione numerica del server SQL 2005
- 27. Il compilatore non avvisa sulla perdita di precisione?
- 28. È indicativo di una perdita di memoria in Java?
- 29. Esiste un suffisso letterale in virgola mobile in C++ per fare una precisione doppia al numero?
- 30. perdita imprevisto di precisione quando si divide doppie
Se la perdita di precisione è un problema, ti consiglio di utilizzare BigDecimal anziché double. –
Sì, il punto centrale di questa domanda è vedere quanto è grande la perdita. il doppio occupa 8 byte, mentre BigDecimal attorno ai 40 e ho bisogno di memorizzare molti punti di dati. – Bober02
Quando si eseguono molte operazioni in virgola mobile, il guadagno in termini di prestazioni dell'uso delle primitive anziché degli oggetti può essere significativo. – Cephalopod