2015-02-12 3 views
6

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ämlich ULONG_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.

+0

Das Programm gibt die erwartete Ausgabe in Visual Studio, und in meinem VM (Ubuntu 10.04, gcc 4.4.3). –

Antwort

3

Dies scheint in gcc 4.8 ein Fehler zu sein. Ich habe das gleiche Verhalten wie du mit 4.8, aber gcc 4.9 und clang zeigen das korrigierte Verhalten.

+0

Können Sie überprüfen, ob es sich um einen Fehler handelt? Ich könnte UB sein, in diesem Fall ist sogar 4.8 * "korrekt" *. – user694733

+1

@ user694733: Es ist nur im nächsten Absatz von dem, was Sie zitiert: * Wenn der Wert ist im Wertebereich umgewandelt wird, die dargestellt werden können, kann aber nicht genau dargestellt werden, ist das Ergebnis entweder der nächsthöheren oder nächstniedrigere darstellbarer Wert, ausgewählt in einer implementierungsspezifischen Weise. * –

+0

Das ist richtig zu sein scheint. Wenn "long" 32-Bit auf dieser Plattform ist, sollte "float" genügend Bandbreite haben, in diesem Fall ist UB ausgeschlossen. – user694733

Verwandte Themen