Ich weiß, dass die ganzzahligen Werte 0
und -0
im Wesentlichen gleich sind. Aber ich frage mich, ob es möglich ist, zwischen ihnen zu unterscheiden.
Woher weiß ich beispielsweise, ob eine Variable zugewiesen wurde -0
?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
Ist der -0
im Speicher gespeicherte Wert genauso wie 0
?
c++
int
zero
negative-number
Filip Minx
quelle
quelle
int
das Zweierkomplement dargestellt wird (bei weitem das am häufigsten anzutreffende)0
und-0
die identische bitweise Darstellung aufweisen.int
. Siehe die Komplementcodierung von Ones .Antworten:
Dies hängt von der Maschine ab, auf die Sie abzielen.
Auf einer Maschine, die eine 2er-Komplementdarstellung für Ganzzahlen verwendet, gibt es auf Bitebene keinen Unterschied zwischen
0
und-0
(sie haben dieselbe Darstellung).Wenn Ihre Maschine die eigene Ergänzung verwendet , könnten Sie dies definitiv tun
Offensichtlich geht es um die native Unterstützung . Prozessoren der x86-Serie bieten native Unterstützung für die komplementäre Darstellung von vorzeichenbehafteten Zahlen. Die Verwendung anderer Darstellungen ist definitiv möglich, wäre jedoch wahrscheinlich weniger effizient und erfordert mehr Anweisungen.
(Wie JerryCoffin auch bemerkte: Auch wenn das eigene Komplement hauptsächlich aus historischen Gründen betrachtet wurde, sind vorzeichenbehaftete Größenrepräsentationen immer noch ziemlich häufig und haben eine separate Darstellung für negative und positive Nullen.)
quelle
0
und-0
ist anders ? Ich hätte ehrlich gesagt erwartet, dass es sich eher so verhält, als würde es zwei Bit-Darstellungen mit demselben Wert zulassen, und Ihr Programm kann jedes verwenden, nach dem es sich anfühlt.-0
, dh das Ergebnis der Anwendung des unären-
Operators auf die Ganzzahlkonstante0
, eine negative Nulldarstellung ist. Unabhängig von der Darstellung sagt der Standard niemals0
und-0
sind mathematisch unterschiedliche Werte, nur dass es möglicherweise ein negatives Null-Bitmuster gibt. Wenn ja, stellt es immer noch den gleichen numerischen Wert dar, 0.Für eine
int
(in der fast universellen "2er-Komplement" -Darstellung) sind die Darstellungen von0
und-0
gleich. (Sie können für andere Zahlendarstellungen unterschiedlich sein, z. B. Gleitkomma nach IEEE 754.)quelle
Beginnen wir mit der Darstellung von 0 im 2er-Komplement (natürlich gibt es viele andere Systeme und Darstellungen, hier beziehe ich mich auf diese spezifische), vorausgesetzt 8-Bit, Null ist:
Lassen Sie uns nun alle Bits umdrehen und 1 addieren, um das 2er-Komplement zu erhalten:
wir haben
0000 0000
, und das ist auch die Darstellung von -0.Beachten Sie jedoch, dass im Komplement von 1 die vorzeichenbehaftete 0 0000 0000 ist, -0 jedoch 1111 1111.
quelle
Ich habe mich entschlossen, diese Antwort offen zu lassen, da C- und C ++ - Implementierungen normalerweise eng miteinander verbunden sind, aber tatsächlich nicht dem C-Standard entspricht, wie ich dachte. Der Punkt bleibt, dass der C ++ - Standard nicht spezifiziert, was in solchen Fällen passiert. Es ist auch wichtig, dass Nicht-Zweier-Komplement-Darstellungen in der realen Welt äußerst selten sind und dass sie, selbst wenn sie existieren, den Unterschied in vielen Fällen oft verbergen, anstatt ihn als etwas zu entlarven, das jemand leicht erwarten könnte, zu entdecken.
Das Verhalten negativer Nullen in den Ganzzahldarstellungen, in denen sie existieren, ist im C ++ - Standard nicht so streng definiert wie im C-Standard. Es wird jedoch die C-Norm (ISO / IEC 9899: 1999) als normative Referenz auf höchster Ebene angeführt [1.2].
Im C-Standard [6.2.6.2] kann eine negative Null nur das Ergebnis von bitweisen Operationen oder Operationen sein, bei denen bereits eine negative Null vorhanden ist (z. B. Multiplizieren oder Teilen einer negativen Null mit einem Wert oder Hinzufügen einer negativen Null zu Null) - Wenn Sie den unären Minusoperator auf einen Wert einer normalen Null anwenden, wie in Ihrem Beispiel, wird daher garantiert eine normale Null erhalten.
Selbst in den Fällen, in denen eine negative Null erzeugt werden kann , gibt es keine Garantie dafür, selbst auf einem System, das eine negative Null unterstützt:
Daher können wir schließen: Nein, es gibt keinen zuverlässigen Weg, um diesen Fall zu erkennen. Auch wenn nicht die Tatsache, dass Darstellungen ohne Zweierkomplement in modernen Computersystemen sehr ungewöhnlich sind.
Der C ++ - Standard erwähnt seinerseits den Begriff "negative Null" nicht und diskutiert die Details der vorzeichenbehafteten Größe und der eigenen Komplementdarstellungen nur sehr wenig, mit Ausnahme der Anmerkung [3.9.1 Abs. 7], dass sie zulässig sind.
quelle
_Bool
oder_Complex
oder bezeichnet initializers oder Verbindung Literale in C ++). Der C ++ - Standard weiß, wie man den C-Standard einbindet, wenn er möchte - z. B. [basic.fundamental] / p3: "Die vorzeichenbehafteten und vorzeichenlosen Ganzzahltypen müssen die im C-Standard, Abschnitt 5.2.4.2.1, angegebenen Einschränkungen erfüllen."Wenn Ihre Maschine unterschiedliche Darstellungen für
-0
und hat+0
,memcmp
können Sie diese unterscheiden.Wenn Füllbits vorhanden sind, kann es tatsächlich auch mehrere Darstellungen für andere Werte als Null geben.
quelle
In der C ++ - Sprachspezifikation gibt es keine negative Null .
Die einzige Bedeutung, die diese beiden Wörter haben, ist der unäre Operator, auf den
-
angewendet wird0
, ebenso wie drei plus fünf nur der binäre Operator ist+
, der auf3
und angewendet wird5
.Wenn es eine eindeutige negative Null gäbe, wäre das Zweierkomplement (die häufigste Darstellung von Ganzzahltypen) eine unzureichende Darstellung für C ++ - Implementierungen, da es keine Möglichkeit gibt, zwei Formen von Null darzustellen.
Im Gegensatz dazu haben Gleitkommawerte (nach IEEE) getrennte positive und negative Nullen. Sie können beispielsweise unterschieden werden, wenn 1 durch sie geteilt wird. Positive Null erzeugt positive Unendlichkeit; Eine negative Null erzeugt eine negative Unendlichkeit.
Wenn es jedoch unterschiedliche Speicherdarstellungen von int 0 (oder einem int oder einem anderen Wert eines anderen Typs) gibt, können Sie Folgendes
memcmp
feststellen:In diesem Fall würden die beiden Werte außerhalb der direkten Speicheroperationen natürlich immer noch genauso funktionieren.
quelle
Zur Vereinfachung fand ich es einfacher zu visualisieren.
Der Typ int (_32) wird mit 32 Bit gespeichert . 32 Bit bedeutet 2 ^ 32 = 4294967296 eindeutige Werte . Also:
Der vorzeichenlose int- Datenbereich liegt zwischen 0 und 4.294.967.295
Bei negativen Werten hängt es davon ab, wie sie gespeichert werden. Im Fall
Im Falle des One-Komplements existiert der Wert -0.
quelle
int
nicht in 32 Bit gespeichert ist, sind heutzutage beliebter als Plattformen mit eigener Ergänzung.