Warum ergibt der Ausdruck (int) + 1e10 nicht -2147483648, wie CSAPP beschreibt? [Duplikat]
Ich lese CS: APP (ein x86-64-Assembly / Low-Level-Lehrbuch) und es erwähnt:
Von
float
oderdouble
bisint
wird der Wert auf Null gerundet. Zum Beispiel1.999
wird auf umgerechnet werden1
, während−1.999
wird umgewandelt werden−1.
Ferner Überlauf der Wert kann. Die C-Standards legen für diesen Fall kein festes Ergebnis fest. Intel-kompatible Mikroprozessoren bezeichnen das Bitmuster [10 ... 00] (TMinw
für die Wortgrößew
) als einen ganzzahligen unbestimmten Wert. Jede Konvertierung von Gleitkomma in Ganzzahl, die keine vernünftige Ganzzahlnäherung zuweisen kann, ergibt diesen Wert. Somit(int) +1e10
ergibt der Ausdruck-2147483648
und erzeugt einen negativen Wert aus einem positiven.
Was sind hier erwähnte Intel-kompatible Mikroprozessoren ? x86
Architektur einschließlich AMD-Serie?
Wie auch immer, ich habe einen Intel i5 mit Win10 64-Bit-Computer und habe es unter Visual Studio versucht:
#include <iostream>
using namespace std;
int main() {
int b = (int)+1e10;
cout << b << endl;
}
und wird 1410065408
als Ausgabe erhalten.
Auch ich habe es versucht int32_t
und bekomme es 1410065408
auch.
Warum habe ich nicht das Ergebnis, -2147483648
das [10 ... 00]
im Buch beschrieben wird?
Antworten
Selbst wenn der verwendete Prozessor "Jede Konvertierung von Gleitkomma in Ganzzahl, die keine vernünftige Ganzzahlnäherung zuweisen kann, ergibt diesen Wert" hat, muss der Compiler dem nicht folgen, da er anderen Code verwenden kann, um das Ziel zu erreichen.
Insbesondere können Werte, die zur Compilerzeit wie bestimmt werden some_32_bit_int = (int)+1e10;
können, einen Wert wie erhalten some_32_bit_int = 10000000000 & 0xFFFFFFFF;
oder der 1410065408
von einem Prozessor völlig unabhängig ist.
Wenn der Wert des Integralteils nicht durch den Integer-Typ dargestellt werden kann, ist das Verhalten undefiniert.
C17dr § 6.3.1.4 1
Das Buch beschreibt den Prozessor, nicht den Compiler.