6 Stimmen

Wie erhält man ein -0 Ergebnis in Fließkommaberechnungen und unterscheidet es von +0 in C#?

In der MSDN-Dokumentation wird erwähnt, dass double Typ schließt negative Nullen ein. Allerdings sind beide -1.0 / double.PositiveInfinity y -double.Epsilon / 2 scheinen normal 0 zurückzugeben (und gleich mit ihr zu vergleichen). Wie kann ich -0 erhalten?

16voto

Brian Punkte 24901

Hier ist ein praktisches Beispiel für die Unterscheidung zwischen den beiden, ohne die Bits zu untersuchen. MSDN-Links aquí y aquí hat mich bei der Erstellung dieses Beispiels unterstützt.

static void Main(string[] args)
{
    float a = 5 / float.NegativeInfinity;
    float b = 5 / float.PositiveInfinity;
    float c = 1 / a;
    float d = 1 / b;
    Console.WriteLine(a);
    Console.WriteLine(b);
    Console.WriteLine(c);
    Console.WriteLine(d);
}

Ausgabe:

0
0
-Infinity
Infinity

Beachten Sie, dass -0 und 0 bei Vergleichen, Ausgaben usw. gleich aussehen. Aber wenn Sie 1 durch sie teilen, erhalten Sie -Infinity oder Infinity, je nachdem, welche Null Sie haben.

3voto

Simon P Stevens Punkte 26735

Die negative Null hat mit der Art und Weise zu tun, wie die Zahl im Binärformat gespeichert wird, und nicht mit einem real erreichbaren Ergebnis einer mathematischen Berechnung.

Bei der Speicherung von Fließkommazahlen wird das oberste Bit häufig zur Kennzeichnung des Vorzeichens verwendet. Damit bleiben 31 Bits für Daten (in einem 32-Bit-Fließkommawert), so dass es eigentlich zwei Darstellungen für Null gibt.

00000000 00000000 00000000 00000000
Oder
00000000 00000000 00000000 00000001

Beide stehen für Null, aber einer mit negativem Vorzeichen.

Natürlich würde dies normalerweise passieren, wenn Sie die höchstmögliche positive Zahl inkrementieren, würde sie auf negative Null zurücklaufen.

In .net denke ich jedoch, dass der Typ standardmäßig Überlaufprüfungen durchführt und eine Ausnahme auslöst, anstatt einen Überlauf zuzulassen, so dass die einzige Möglichkeit, diesen Wert wirklich zu archivieren, darin besteht, ihn direkt festzulegen. Außerdem sollte -0 immer gleich +0 vergleichen.

Mehr dazu finden Sie unter Wikipeida

2voto

Zanoni Punkte 28468

Eine Möglichkeit ist die Verwendung von BitConverter.GetBytes. Wenn Sie die Bytes überprüfen, werden Sie sehen, dass das Vorzeichenbit für den Wert tatsächlich gesetzt ist, was bedeutet, dass er negativ ist.

byte[] zeroBytes = BitConverter.GetBytes(zero);
byte[] negZeroBytes = BitConverter.GetBytes(negZero);

bool sameBytes = zeroBytes[7] == negZeroBytes[7];

2voto

Joel Goodwin Punkte 4866

Versuchen Sie dies. Wenn pz eine positive Null ist und nz negativ Null ist:

Double.PositiveInfinity/pz => Double.PositiveInfinity
Double.PositiveInfinity/nz => Double.NegativeInfinity

Ich habe dies von ECMA C#-Spezifikation .

Die negative Null erhält man, indem man eine beliebige positive Zahl durch die negative Unendlichkeit dividiert:

10.0/Double.NegativeInfinity

0voto

Alexey Romanov Punkte 160158

Nach Überprüfung stelle ich fest, dass -1.0 / double.PositiveInfinity tut return -0. In der Tat, 1.0 / (-1.0 / double.PositiveInfinity) gibt zurück. -infinity .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X