2012-04-01 11 views
13

Warum ist d ungleich b in diesem Beispiel?seltsames Berechnungsergebnis

unsigned int z = 176400; 
    long a = -4; 
    long b = a*z/1000; //b=4294261 
    long c = a*z; // c=-705600 
    long d = c/1000; // d =-705 

Ich verwende Visual Studio 2008, Windows XP, core2duo. Danke.

+6

... Weil d == c/1000. Ist das ein echtes Leben? – outis

+2

@crushanator Tatsächlich ist a auch nicht gleich d. Hast du das gesehen? –

+3

Warum ist 1 in diesem Beispiel nicht gleich 2: 'int a = 1; int b = 2; '? –

Antwort

5

Es sieht so aus, als ob Sie eine Plattform verwenden, bei der int und long die gleiche Größe haben. (Ich dies durch die Tatsache gefolgert haben, dass, wenn long der Lage war, alle gültigen Werte zu halten, unsigned int Sie würden das Verhalten nicht sehen, die Sie sehen.)

Dies bedeutet, dass in dem Ausdruck a*z, sowohl a und z werden in unsigned long konvertiert und das Ergebnis hat den Typ unsigned long. (ISO/IEC 14882: 2011, 5 [Ausdruck]/9 ... "Andernfalls sollten beide Operanden in den vorzeichenlosen Integer-Typ umgewandelt werden, der dem Typ des Operanden mit Ganzzahl mit Vorzeichen entspricht.")

c ist das Ergebnis der Umwandlung dieses Ausdrucks von unsigned long zu long und in Ihrem Fall führt dies zu einem Ergebnis der Implementierung (das zufällig negativ ist), da der positive Wert a*z nicht in einer signierten long darstellbar ist. In c/1000 wird 1000 in long konvertiert und long Teilung durchgeführt (kein Wortspiel beabsichtigt), was zu einem long führt (was zufällig negativ ist) und wird gespeichert in d.

In der Ausdrücken a*z/1000, 1000 (ein Ausdruck des Typs int) auf unsigned long umgewandelt und die Teilung zwischen zwei unsigned long was zu einem positiven Ergebnis durchgeführt. Dieses Ergebnis ist als long darstellbar und der Wert ist unverändert beim Umwandeln in long und Speichern zu b.

+0

Dies ist in der Tat auf MS C Compiler der Fall. – Inisheer

+0

Signed Overflow ist undefiniertes Verhalten, aber der Weg. –

+1

@KerrekSB: Ja, aber in diesem Beispiel gibt es keinen überzeichneten Überlauf. –