it-swarm.com.de

Warum ist negative Null wichtig?

Ich bin verwirrt darüber, warum uns unterschiedliche Darstellungen für positive und negative Null wichtig sind.

Ich erinnere mich vage an das Lesen von Behauptungen, dass eine negative Nulldarstellung bei der Programmierung mit komplexen Zahlen äußerst wichtig ist. Ich hatte noch nie die Gelegenheit, Code mit komplexen Zahlen zu schreiben, daher bin ich ein wenig ratlos darüber, warum dies der Fall sein würde.

Wikipedia-Artikel zum Konzept ist nicht besonders hilfreich; es macht nur vage Behauptungen über vorzeichenbehaftete Null, was bestimmte mathematische Operationen im Gleitkomma vereinfacht, wenn ich es richtig verstehe. Diese Antwort listet einige Funktionen auf, die sich unterschiedlich verhalten, und möglicherweise kann aus den Beispielen etwas abgeleitet werden, wenn Sie mit deren Verwendung vertraut sind. (Obwohl das spezielle Beispiel der komplexen Quadratwurzeln geradezu falsch aussieht , da die beiden Zahlen mathematisch äquivalent sind, es sei denn, ich habe ein Missverständnis.) Aber Ich konnte keine klare Aussage darüber finden, in welche Schwierigkeiten Sie geraten würden, wenn es nicht da wäre. Die mathematischeren Ressourcen, die ich finden konnte, besagen, dass es aus mathematischer Sicht keinen Unterschied zwischen den beiden gibt, und der Wikipedia-Artikel scheint darauf hinzudeuten, dass dies nur selten außerhalb des Rechnens gesehen wird, abgesehen von der Beschreibung von Grenzen.

Warum ist eine negative Null beim Rechnen wertvoll? Ich bin sicher, ich vermisse nur etwas.

67
jpmc26

Sie müssen berücksichtigen, dass in der FPU-Arithmetik 0 nicht unbedingt genau Null bedeuten muss, sondern auch einen Wert, der zu klein ist, um unter Verwendung eines bestimmten Datentyps dargestellt zu werden, z.

a = -1 / 1000000000000000000.0

a ist zu klein, um korrekt durch float (32 Bit) dargestellt zu werden, daher wird es auf -0 "gerundet".

Nehmen wir nun an, unsere Berechnung wird fortgesetzt:

b = 1 / a

Da a float ist, führt dies zu -infinity, was ziemlich weit von der richtigen Antwort von -1000000000000000000.0 entfernt ist

Berechnen wir nun b, wenn es kein -0 gibt (also wird a auf +0 gerundet):

b = 1 / +0
b = +infinity

Das Ergebnis ist wegen der Rundung wieder falsch, aber jetzt ist es "falscher" - nicht nur numerisch, sondern vor allem wegen des unterschiedlichen Vorzeichens (Ergebnis der Berechnung ist + unendlich, korrektes Ergebnis ist -10000000000000000.00).

Man könnte immer noch sagen, dass es nicht wirklich wichtig ist, da beide falsch sind. Das Wichtige ist, dass es viele numerische Anwendungen gibt, bei denen das wichtigste Ergebnis der Berechnung das Vorzeichen ist - z. Wenn Sie mit einem Algorithmus für maschinelles Lernen entscheiden, ob Sie an der Kreuzung nach links oder rechts abbiegen möchten, können Sie den positiven Wert interpretieren => nach links abbiegen, den negativen Wert => nach rechts abbiegen. Die tatsächliche "Größe" des Werts ist nur "Konfidenzkoeffizient".

76
qbd

Wie erstellt man zuerst eine -0? Es gibt zwei Möglichkeiten: (1) Führen Sie eine Gleitkommaoperation durch, bei der das mathematische Ergebnis negativ ist, aber so nahe bei Null liegt, dass es auf Null und nicht auf eine Zahl ungleich Null gerundet wird. Diese Berechnung ergibt eine -0. (b) Bestimmte Operationen mit Nullen: Multiplizieren Sie eine positive Null mit einer negativen Zahl oder dividieren Sie eine positive Null durch eine negative Zahl oder negieren Sie eine positive Null.

Eine negative Null vereinfacht die Multiplikation und Division ein wenig. Das Vorzeichen von x * y oder x/y ist immer das Vorzeichen von x, exklusiv oder das Vorzeichen von y. Ohne negative Null müsste eine zusätzliche Prüfung durchgeführt werden, um -0 durch +0 zu ersetzen.

Es gibt einige sehr seltene Situationen, in denen es nützlich ist. Sie können überprüfen, ob das Ergebnis einer Multiplikation oder Division mathematisch größer oder kleiner als Null ist, auch wenn ein Unterlauf vorliegt (sofern Sie wissen, dass das Ergebnis keine mathematische Null ist). Ich kann mich nicht erinnern, jemals Code geschrieben zu haben, bei dem es einen Unterschied macht.

Optimierende Compiler hassen -0. Beispielsweise können Sie x + 0.0 nicht durch x ersetzen, da das Ergebnis nicht x sein sollte, wenn x -0.0 ist. Sie können x * 0.0 nicht durch 0.0 ersetzen, da das Ergebnis -0.0 sein sollte, wenn x <0 oder x -0.0 ist.

8
gnasher729

C # Double gemäß IEEE 754

    double a = 3.0;
    double b = 0.0;
    double c = -0.0;

    Console.WriteLine(a / b);
    Console.WriteLine(a / c);

drucke:

Infinity
-Infinity

eigentlich um ein wenig zu erklären ...

Double d = -0.0; 

Dies bedeutet etwas viel näher an d = The Limit of x as x approaches 0- Oder The Limit of x as x approaches 0 from the negatives.


Um Philipps Kommentar anzusprechen ...

Grundsätzlich bedeutet negative Null Unterlauf.

Es gibt sehr wenig praktischen Nutzen für negative Null, wenn überhaupt ...

zum Beispiel dieser Code (wieder C #):

double a = -0.0;
double b = 0.0;

Console.WriteLine(a.Equals(b));
Console.WriteLine(a==b);
Console.WriteLine(Math.Sign(a));

ergibt dieses Ergebnis:

True
True
0

Informell zu erklären: Alle speziellen Werte, die ein IEEE 754-Gleitkomma haben kann (positive Unendlichkeit, negative Unendlichkeit, NAN, -0,0), haben im praktischen Sinne keine Bedeutung. Sie können keinen physischen Wert oder einen Wert darstellen, der in der Berechnung der "realen Welt" sinnvoll ist. Was sie bedeuten, ist im Grunde Folgendes:

  • positive Unendlichkeit bedeutet einen Überlauf am positiven Ende, den ein Gleitkomma darstellen kann
  • negative Unendlichkeit bedeutet einen Überlauf am positiven Ende, den ein Gleitkomma darstellen kann
  • eine negative Null bedeutet einen Unterlauf und die Operanden hatten entgegengesetzte Vorzeichen
  • positive Null kann bedeutet einen Unterlauf und die Operanden hatten das gleiche Vorzeichen
  • NAN bedeutet, dass Ihre Berechnung wie sqrt(-7) eindeutig undefiniert ist oder kein Limit wie 0/0 Oder wie PositiveInfinity/PositiveInfinity Hat.
6
AK_

Die Frage, wie dies mit Berechnungen komplexer Zahlen zusammenhängt, ist der Kern dessen, warum sowohl +0 als auch -0 im Gleitkomma existieren. Wenn Sie sich überhaupt mit komplexer Analyse befassen, stellen Sie schnell fest, dass kontinuierliche Funktionen von komplex zu komplex normalerweise nicht als "einwertig" behandelt werden können, es sei denn, man übernimmt die "höfliche Fiktion", dass die Ergebnisse eine sogenannte "Riemann-Oberfläche" bilden. Zum Beispiel weist der komplexe Logarithmus jedem Eingang unendlich viele Ausgänge zu; Wenn Sie sie zu einer kontinuierlichen Ausgabe verbinden, erhalten Sie alle Realteile, die eine unendliche Korkenzieheroberfläche um den Ursprung bilden. Eine kontinuierliche Kurve, die die reale Achse "von der positiv-imaginären Seite nach unten" kreuzt, und eine andere Kurve, die sich "um den Pol wickelt" und die reale Achse "von der negativ-imaginären Seite nach oben" kreuzt, nimmt auf der realen Achse unterschiedliche Werte an, weil Sie gehen über verschiedene "Blätter" der Riemannschen Oberfläche.

Wenden Sie dies nun auf ein numerisches Programm an, das mit komplexen Gleitkommazahlen berechnet. Die Aktion, die nach einer bestimmten Berechnung ausgeführt wird, kann sehr unterschiedlich sein, je nachdem, auf welchem ​​'Blatt' sich das Programm gerade 'befindet', und das Vorzeichen des zuletzt berechneten Ergebnisses sagt Ihnen wahrscheinlich, welches 'Blatt'. Angenommen, das Ergebnis war Null? Denken Sie daran, hier bedeutet "Null" wirklich "zu klein, um richtig dargestellt zu werden". Wenn die Berechnung jedoch dazu führen könnte, dass das Vorzeichen erhalten bleibt (d. H. Erinnern Sie sich an welches 'Blatt'), wenn das Ergebnis Null ist, kann der Code das Vorzeichen überprüfen und auch in dieser Situation die richtige Aktion ausführen.

5
PJM

Der Grund ist einfacher als gewöhnlich

Natürlich gibt es viele Hacks, die wirklich gut aussehen und nützlich sind (wie das Runden auf -0.0 oder +0.0 aber nehmen wir an, wir haben eine Darstellung von signiertem int mit einem Minus-/Pluszeichen am Anfang (ich weiß, dass dies normalerweise durch U2-Binärcode in ganzen Zahlen aufgelöst wird, aber nehmen wir eine weniger komplexe Darstellung von double an):

0 111 = 7
^ sign

Was ist, wenn es eine negative Zahl gibt?

1 111 = -7

Okay, so einfach. Stellen wir also 0 dar:

0 000 = 0

Das ist auch gut so. Aber was ist mit 1 000? Muss es eine verbotene Nummer sein? Besser nicht.

Nehmen wir also an, es gibt zwei Arten von Nullen:

0 000 = +0
1 000 = -0

Nun, das wird unsere Berechnungen vereinfachen und glücklicherweise einige zusätzliche Funktionen abrunden. Also die +0 und -0 kommen nur von Problemen mit der binären Darstellung.

1
Dawid Pura