webentwicklung-frage-antwort-db.com.de

So ermitteln Sie die maximale Genauigkeit für das Doppelte

Ich versuche zu ermitteln, wie hoch die maximale Präzision für ein Double ist. In den Kommentaren zur akzeptierten Antwort in diesem Link - Präzision in Java beibehalten @PeterLawrey gibt die maximale Genauigkeit in 15 an.

Wie bestimmen Sie das?

13
Shivam Sinha

@PeterLawrey gibt maximale Präzision in 15 an.

Das hat er eigentlich gar nicht gesagt. Was er sagte, war:

double hat 15 Dezimalstellen Genauigkeit

und er ist falsch. Sie haben 15 Dezimalstellen Ziffern Genauigkeit.

Die Anzahl der Dezimalstellen in einer beliebigen Anzahl wird durch das Protokoll der Basis 10 angegeben. 15 ist der Standwert des Protokolls10(253-1), wobei 53 die Anzahl der Bits der Mantisse (einschließlich des implizierten Bits) ist, wie in Javadoc und IEEE 754 beschrieben, und 253-1 ist daher der maximal mögliche Mantissenwert. Der tatsächliche Wert ist 15,954589770191003298111788092734 bis zu den Grenzen des Windows-Rechners. 

Es ist völlig falsch, es als "Dezimalstellen der Genauigkeit" zu bezeichnen. Eine double hat 15 Dezimalzahlen Ziffern mit Genauigkeit falls sie alle vor dem Dezimalzeichen stehen. Bei Zahlen mit gebrochenen Teilen können Sie aufgrund der Dezimalstellen-Darstellung viel mehr als 15 Stellen erhalten Inkommensurabilität von Dezimal- und Binärbrüchen. 

9
user207421

Sie können es auch direkt "messen": 

for(double d = 1 ; d > 0 ; d/=2) System.out.println(d);

Die Idee dieses Codes besteht darin, mit einem einzigen Bit die kleinste Zahl zu erreichen. Sie beginnen also mit 1 (hat nur 1 Bit) und dividiert durch zwei (wodurch Bits binär nach rechts verschoben werden), bis Sie das letzte Bit erreichen. Die letzte von dieser Schleife gedruckte Zahl lautet: 

4.9E-324

0
Maljam

Führen Sie diesen Code aus und sehen Sie, wo er aufhört

public class FindPrecisionDouble {
  static public void main(String[] args) {
    double x = 1.0;
    double y = 0.5;
    double epsilon = 0;
    int nb_iter = 0;
    while ((nb_iter < 1000) && (x != y)) {
        System.out.println(x-y);
        epsilon = Math.abs(x-y);
        y = ( x + y ) * 0.5;
    }
    final double prec_decimal = - Math.log(epsilon) / Math.log(10.0);
    final double prec_binary = - Math.log(epsilon) / Math.log(2.0);
    System.out.print("On this machine, for the 'double' type, ");
    System.out.print("epsilon = " );
    System.out.println( epsilon );
    System.out.print("The decimal precision is " );
    System.out.print( prec_decimal );
    System.out.println(" digits" );
    System.out.print("The binary precision is " );
    System.out.print( prec_binary );
    System.out.println(" bits" );
  }
}

Die Variable y wird zum kleinsten Wert, der sich von 1.0 unterscheidet. Auf meinem Computer (Mac Intel Core i5) stoppt es bei 1.1102...E-16. Anschließend wird die Genauigkeit (dezimal und binär) ausgegeben.

Wie in https://en.wikipedia.org/wiki/Machine_epsilon angegeben, kann die Gleitkomma-Genauigkeit mit dem Epsilon-Wert ..__ geschätzt werden. Es ist "die kleinste Zahl, die, wenn sie zu einem addiert wird, ergibt ein anderes Ergebnis als eins "(Ich habe eine kleine Variation gemacht: 1-e statt 1 + e, aber die Logik ist die gleiche)

Ich erkläre es in Dezimalzahlen: Wenn Sie eine Genauigkeit von 4 Dezimalstellen haben, können Sie 1,0000 - 0,0001 ausdrücken, aber Sie können die Zahl 1,00000-0,00001 nicht ausdrücken (es fehlt die 5. Dezimalstelle). In diesem Beispiel ist das Epsilon mit einer Genauigkeit von 4 Dezimalstellen 0,0001. Das Epsilon misst direkt die Gleitkomma-Genauigkeit. Einfach in binär umwandeln. 

Bearbeiten Ihre Frage hat die Frage "Wie ermitteln ..." Die Antwort, die Sie suchten, war mehr eine Erklärung als eine Methode zur Bestimmung der Genauigkeit (mit der von Ihnen akzeptierten Antwort). Wenn Sie diesen Code auf einer Maschine ausführen, wird die Genauigkeit für den Typ "double" auf jeden Fall festgelegt.

0
Sci Prog