Heim >Backend-Entwicklung >C++ >Warum erzeugen C# und C beim Formatieren von Doubles unterschiedliche Ausgaben?

Warum erzeugen C# und C beim Formatieren von Doubles unterschiedliche Ausgaben?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2025-01-04 19:27:44441Durchsuche

Why Do C# and C Produce Different Output When Formatting Doubles?

Doppelte Formatierung für die Ausgabe in C#

In einem kürzlich durchgeführten Experiment wurde versucht, die Ausgabeformatierungsfunktionen von C in C# zu emulieren. Es wurden jedoch Abweichungen zwischen der erwarteten und der tatsächlichen Ausgabe beobachtet.

Der C-Code:

double i = 10 * 0.69;
printf("%f\n", i);
printf("  %.20f\n", i);
printf("+ %.20f\n", 6.9 - i);
printf("= %.20f\n", 6.9);

erzeugte die folgende Ausgabe:

6.900000
6.89999999999999946709
+ 0.00000000000000088818
= 6.90000000000000035527

Der C#-Code:

double i = 10 * 0.69;
Console.WriteLine(i);
Console.WriteLine(String.Format("  {0:F20}", i));
Console.WriteLine(String.Format("+ {0:F20}", 6.9 - i));
Console.WriteLine(String.Format("= {0:F20}", 6.9));

nachgegeben:

6.9
6.90000000000000000000
+ 0.00000000000000088818
= 6.90000000000000000000

Trotz meines Erscheinens B. 6,89999999999999946709 im Debugger, rundet die C#-Formatierung den Wert auf 15 signifikante Dezimalstellen, bevor das Format angewendet wird.

Dieses unerwartete Verhalten ist darauf zurückzuführen, dass .NET intern Doubles mithilfe einer Binärdarstellung speichert. Vor der Formatierung konvertiert .NET das Double in eine Dezimalzeichenfolge, was zwangsläufig zu Rundungsfehlern führt.

Um dieses Problem zu vermeiden, kann man entweder:

  • Auf die genaue Dezimalzahl zugreifen Wert des Doubles: Konstruieren Sie eine Zeichenfolgendarstellung des Dezimalwerts, indem Sie die internen Binärbits extrahieren manuell.
  • Verwenden Sie eine benutzerdefinierte Formatierungsbibliothek: Nutzen Sie die DoubleConverter-Klasse von Jon Skeet, die Methoden zum Abrufen des genauen Dezimalwerts eines Doubles und zum Runden der Ausgabe auf eine bestimmte Genauigkeit bereitstellt.

Das DoubleConverter-Anwendungsbeispiel:

Console.WriteLine(DoubleConverter.ToExactString(i));
Console.WriteLine(DoubleConverter.ToExactString(6.9 - i));
Console.WriteLine(DoubleConverter.ToExactString(6.9));

// 6.89999999999999946709294817992486059665679931640625
// 0.00000000000000088817841970012523233890533447265625
// 6.9000000000000003552713678800500929355621337890625

Das obige ist der detaillierte Inhalt vonWarum erzeugen C# und C beim Formatieren von Doubles unterschiedliche Ausgaben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn