einfache Berechnung, unterschiedliche Ergebnisse in c # und delphi

7

Die Frage ist, warum geben diese Code-Snippets andere Ergebnisse?

%Vor%

und

%Vor%

Der Delphi-Code gibt mir 816, während der c # -Code mir 0 gibt. Mit einem Taschenrechner bekomme ich 775. Kann mir bitte jemand eine detaillierte Erklärung geben?

Vielen Dank!

    
Shunyata Kharg 29.04.2009, 15:55
quelle

8 Antworten

11

Delphi speichert Zwischenwerte als Extended (ein 80-Bit Gleitkommatyp). Dieser Ausdruck ist Extended:

%Vor%

Das Gleiche gilt möglicherweise nicht für C # (ich weiß es nicht). Die zusätzliche Präzision könnte einen Unterschied machen.

    
dan-gph 29.04.2009, 16:18
quelle
10

Beachten Sie, dass Sie hier an der Grenze der Genauigkeit des Datentyps Double sind, was bedeutet, dass die Berechnungen hier nicht genau sind.

Beispiel:

%Vor%

was gesagt werden kann wie:

%Vor%

und so:

%Vor%

In Wirklichkeit wird der Wert in .NET eher wie folgt aussehen:

%Vor%

Beachten Sie die Rundung dort. Daher erhalten Sie auf dieser Ebene nicht die richtigen Antworten.

    
quelle
5

Dies ist sicherlich keine Erklärung für diese genaue Situation, aber es wird helfen, das Problem zu erklären.

Was jeder Informatiker über Gleitkommaarithmetik wissen sollte

    
jellomonkey 29.04.2009 16:00
quelle
4

Ein C # double hat höchstens 16 Stellen Genauigkeit. Wenn Sie 4.271343859532459e + 18 nehmen und mit 5 multiplizieren, erhalten Sie eine Anzahl von 19 Ziffern. Sie möchten eine Zahl mit nur 3 Ziffern haben. Double kann das nicht machen.

In C # kann der Decimal-Typ mit diesem Beispiel umgehen - wenn Sie das 123M-Format zum Initialisieren der Dezimalwerte verwenden.

%Vor%

Das ergibt 775,00, was die richtige Antwort ist.

    
Jack Bolding 29.04.2009 16:17
quelle
3

Jede Berechnung wie diese wird zu Dramen mit typischer Gleitkommaarithmetik führen. Je größer der Unterschied in der Skalierung der Zahlen ist, desto größer ist die Wahrscheinlichkeit eines Genauigkeitsproblems.

Ссылка gibt einen guten Überblick.

    
JDU 29.04.2009 16:04
quelle
0

Ich denke, dass dies ein Fehler ist, der durch die begrenzte Genauigkeit verursacht wird (Vor allem, weil Doppel statt Ganzzahlen verwendet werden). Vielleicht ist d1 nach der Zuweisung nicht dasselbe. d2 * d2 wird sicherlich anders sein als der korrekte Wert, da er größer als 2 ^ 32 ist.

Da 5 * d1 sogar größer als 2 ^ 64 ist, hilft auch die Verwendung von 64-Bit-Ganzzahlen nicht. Sie müssten Bignums oder eine 128-Bit-Integer-Klasse verwenden, um das korrekte Ergebnis zu erhalten.

    
schnaader 29.04.2009 16:04
quelle
0

Wie andere Leute bereits betont haben, ist die doppelte Genauigkeit nicht genau genug für den Umfang der Berechnungen, die Sie durchführen möchten. Delphi verwendet standardmäßig "erweiterte Genauigkeit", wodurch weitere 16 Bit über Double hinzugefügt werden, um eine genauere Berechnung zu ermöglichen. Das .NET-Framework verfügt nicht über einen Datentyp mit erweiterter Genauigkeit.

Ich bin mir nicht sicher, welchen Typ Ihr ​​Rechner verwendet, aber anscheinend macht er etwas anderes als Delphi und C #.

    
Mason Wheeler 29.04.2009 16:46
quelle
0

Wie von den anderen kommentiert, ist das Double für Ihre Berechnung nicht präzise genug. Die Dezimalzahl ist eine gute Alternative, obwohl jemand darauf hingewiesen hat, dass es gerundet wäre, ist es nicht.

  

In C # kann der Decimal-Typ dieses Beispiel nicht einfach verarbeiten, da 4.271343859532459e + 18 auf 427134385959532460000 gerundet wird.

Dies ist nicht der Fall. Die Antwort, wenn Sie Dezimal verwenden, wird korrekt sein. Aber wie er sagte, ist der Bereich anders.

    
Khan 29.04.2009 17:08
quelle

Tags und Links