Warum werden Zahlen mit vielen signifikanten Stellen in C # und JavaScript anders behandelt?

8

Wenn die Nummer von JavaScript und C # doppelt angegeben sind (IEEE 754), warum werden Zahlen mit vielen signifikanten Stellen anders behandelt?

%Vor%

Ich mache mir keine Gedanken darüber, dass IEEE 754 nicht die Nummer 1234123412341234123 darstellen kann. Ich habe Bedenken, dass die beiden Implementierungen für Zahlen, die nicht mit voller Genauigkeit dargestellt werden können, nicht gleich funktionieren.

Dies liegt möglicherweise daran, dass IEEE 754 nicht spezifiziert ist, eine oder beide Implementierungen fehlerhaft sind oder dass sie verschiedene Varianten von IEEE 754 implementieren.

Dieses Problem bezieht sich nicht auf Probleme mit der Ausgabe von Fließkommaformaten in C #. Ich gebe 64-Bit-Ganzzahlen aus. Berücksichtigen Sie Folgendes:

long x = 1234123412341234123; Console.WriteLine(x); // Prints 1234123412341234123 double y = 1234123412341234123; x = Convert.ToInt64(y); Console.WriteLine(x); // Prints 1234123412341234176

Die gleiche Variable gibt verschiedene Zeichenfolgen aus, da die Werte unterschiedlich sind.

    
Hans Malherbe 27.05.2015, 06:57
quelle

3 Antworten

3

Hier gibt es mehrere Probleme ...

Sie verwenden long anstelle von double . Sie müssten schreiben:

%Vor%

oder

%Vor%

Das andere Problem ist, dass .NET double s auf 15 Stellen umwandelt, bevor es in string konvertiert wird (also vorher zum Beispiel mit Console.ToString() ).

Zum Beispiel:

%Vor%

Siehe zum Beispiel Ссылка

Intern ist die Nummer immer noch mit 17 Ziffern, nur wird es mit 15 angezeigt.

Sie können es sehen, wenn Sie a:

%Vor%     
xanatos 27.05.2015, 07:26
quelle
2

Die Zahlen werden nicht anders behandelt, sie werden nur anders dargestellt.

.NET zeigt die Zahl mit 15 signifikanten Ziffern an, während JavaScript sie mit 17 signifikanten Ziffern anzeigt. Die Darstellung eines Double kann 15-17 signifikante Ziffern enthalten, je nachdem, welche Zahl es enthält. In .NET wird nur die Anzahl der Ziffern angezeigt, die die Zahl garantiert immer unterstützt, während in JavaScript alle Ziffern angezeigt werden, die Genauigkeitsbegrenzung jedoch möglicherweise angezeigt wird.

.NET beginnt mit der Verwendung der wissenschaftlichen Notation, wenn der Exponent 15 ist, während JavaScript sie verwendet, wenn der Exponent 21 ist. Das bedeutet, dass JavaScript Zahlen mit 18 bis 20 Ziffern anzeigt, die am Ende mit Nullen aufgefüllt sind.

Wenn Sie in Ihrem Beispiel double in ein long umwandeln, umgehen Sie, wie .NET Double-Dateien anzeigt. Die Zahl wird ohne die Rundung konvertiert, die die Genauigkeitsbegrenzung verbirgt. In diesem Fall sehen Sie den tatsächlichen Wert, der sich im Double befindet. Der Grund dafür, dass es nicht nur Nullen jenseits der 17. Ziffer gibt, ist, dass der Wert in binärer Form und nicht in Dezimalform gespeichert wird.

    
Guffa 27.05.2015 07:28
quelle
1

Haftungsausschluss: Dies basiert auf den Standards Wikipedia-Seite

Gemäß der Wikipedia-Seite für den Standard definiert es, dass eine Dezimalstelle 64 16 Ziffern der Genauigkeit haben sollte.

Es ist die Entscheidung des Herstellers, was mit den zusätzlichen Ziffern gemacht werden sollte.

Sie können also sagen, dass der Standard unterspezifiziert ist, aber diese Zahlen sind nicht so ausgelegt, dass sie trotzdem in die Normenspezifikationen passen. Beide Sprachen haben Möglichkeiten, mit größeren Zahlen umzugehen, daher sind diese Optionen möglicherweise besser für Sie geeignet.

    
Sayse 27.05.2015 07:39
quelle

Tags und Links