Der Titel wird wahrscheinlich schlecht gewählt, aber ich konnte keine gute einzeilige Zusammenfassung für diese Frage finden. Mein Problem ist, dass ich nicht Sinn das, was machen kann mein Compiler tut, und ich frage mich, ob ich einen Fehler im Compiler ... oder in meinem Verständnis der C-Sprache gefunden.Kann ein unsigned long negativ werden, wenn es mit einem float multipliziert wird?
Mein Verständnis ist, dass:
- 1UL == ULONG_MAX
, und das ist sicher, da das Überlaufverhalten von Zahlen ohne Vorzeichen gut definiert ist- das Produkt
(- 1UL) * 1.0f
die Umwandlung des linken Operanden beinhaltet zu schweben, und diese Umwandlung erhält den Wert (nämlichULONG_MAX
) mit Ausnahme der Rundungsfehler
Bisher mein Compiler zustimmt, es sei denn, 1UL
aus einer variablen kommt. Hier ist mein Testprogramm, mit seiner Ausgabe als Kommentar:
#include <stdio.h>
int main(void)
{
unsigned long one = 1;
unsigned long minus_one = - one;
printf("%lu\n", - one); // 18446744073709551615
printf("%g\n", minus_one * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0); // 1.84467e+19
printf("%g\n", (- 1UL) * 1.0f); // 1.84467e+19
printf("%g\n", (- one) * 1.0f); // -1
return 0;
}
Ich kann den letzten Ausgang nicht sinnvoll machen. Ich habe verschiedene Optimierungsebenen und verschiedene Sprachstandards (C90, C99 und C11) mit identischen Ergebnissen ausprobiert. Jeder eine Ahnung?
Umwelt: gcc 4.8.1/Ubuntu Linux 14.04/x86-64 (I32LP64)
bearbeiten: Ich habe gerade bemerkt, dass meine Frage ein Duplikat combination of unary minus and float conversion sein kann.
Das Programm gibt die erwartete Ausgabe in Visual Studio, und in meinem VM (Ubuntu 10.04, gcc 4.4.3). –