Java: aggiungere doppio.min_normal a un doppio non cambia il numero
-
21-12-2019 - |
Domanda
Ho pensato che Min_Normal fosse un valore che potresti aggiungere a un doppio "normale" e il numero cambierà.Per esempio.Aggiungi doppio.min_normal a 0,1D e ottieni un valore diverso da 0,1D, tuttavia la mia comprensione è sbagliata:
public static void test(double val) {
if (val == (val - Double.MIN_NORMAL*1e50d))
System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
else
System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}
.
che produce:
test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000
test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000
test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000
.
Qualcuno pls spiega cosa sta andando contro la mia logica qui, che anche se aggiungo Min_normal Times 1E50D, ho ancora lo stesso numero.
Ho controllato le rappresentazioni binarie e 1 * doppio.min_normal è diverso da 2 * doppio.min_normal, ma sottraendo quelli da qualsiasi cosa eccetto zero non cambia il numero originale.
Soluzione
MIN_NORMAL
è, poiché il Javadoc dice, solo il valore generalizzato di double
più piccolo. Ma ciò non significa che sia qualcosa come 1
per int
s: per i valori del punto flottanti, è semplicemente no standard "EPS" è possibile aggiungere per passare al successivo valore rappresentabile - il " EPS "dipende sempre dall'esponente del dato valore a punto flottante. Ecco perché sono chiamati Floating Punti, alla fine :)
Tuttavia, Java 1.6+ fornisce Math.nextAfter()
che ritorna, per qualsiasi gruppo double
, il successivo o precedente generabile double
.
Le versioni Java più antiche, è possibile sempre scherzare con Double.doubleToLongBits()
, incrementando o decrementare il suo risultato e convertirsi indietro da Double.longBitsToDouble()
; Questo ti fa il successivo o il precedente valore di double
Rappresentabile rappresentabile - nella maggior parte dei casi : Ci sono alcuni casi speciali (NAN, valori infiniti), quindi non è raccomandato a Bloying-Point Newbies :) .
Altri suggerimenti
La doppia ha una precisione limitata.MIN_NORMAL è 2E-1022.Sarà lasciato cadere a meno che il numero che lo aggiungi è anche nel Ballpark di 2E-1000.