2016-06-21 18 views
1

Ich habe folgendes:unsigned int vs unsigned short Unterschied in C++

#include <iostream>           

using namespace std;           

float f1(unsigned int x, unsigned int y)      
{                
    float val;            
    val = float(y-x)/(y+x);         
    return val;            
}                

float f2(unsigned short x, unsigned short y)     
{                
    float val;            
    val = float(y-x)/(y+x);         
    return val;            
}                

int main()             
{                
    cout << f1(9612, 9038) << "\n" << f2(9612, 9038) << endl; 
    return 0;             
}                

Am Ausgang bekomme ich zwei verschiedene Werte von f1 und f2 obwohl ich die Ausgänge erwarten, dass die gleiche sein, da die Funktionen ähnlich sind. Können Sie bitte die Ursache des Unterschieds erklären?

+3

'y' ist kleiner als' x', also ist 'yx' in' f1' eine große positive Zahl, während es in 'f2' entweder eine kleine positive Zahl oder eine kleine negative Zahl ist (abhängig vom relativen Wert) Größen von 'short' und' int' auf Ihrem System) –

+0

Ich habe die Berechnungen ausgeführt und das Ergebnis ist -0.0307774798927614. Vorzeichenlose Typen können keine negativen Werte verarbeiten. – TuukkaX

+0

@TuukkaX: Sie können sicherlich, aber Sie bekommen 2-Komplement. – lorro

Antwort

3

Während beide Funktionen vorzeichenlose Werte verwenden, könnte man denken, dass die Subtraktion zu einer positiven Zahl für beide Werte führen würde. Eine wäre falsch wegen der ganzzahligen Heraufstufung vor der Auswertung der Operatorarithmetik für numerische Typen.

cppreference describes arithmetic operator conversions:

Wenn der Operand einen arithmetischen Operator ist integral oder unscoped Aufzählungstyp geleitet, dann, bevor eine andere Aktion (aber nach dem L-Wert-zu-R-Wert Umwandlung, wo zutreffend), der Operand erfährt integral Beförderung. Wenn ein Operand einen Array- oder Funktionstyp hat, werden Konvertierungen von Array zu Zeiger und von Funktion zu Zeiger angewendet. ...

Integrale Werbung ist, wo diese Konvertierung stattfindet. Zu diesem Thema, cppreference states the following:

Prvalues ​​kleinen integralen Typs (wie char) an prvalues ​​größeren integralen Typen (wie int) umgewandelt werden. Insbesondere akzeptieren arithmetische Operatoren keine Typen, die kleiner als int sind, als Argumente, und Integral-Promotions werden automatisch nach der Konvertierung von lvalue-to-rvalue angewendet, falls zutreffend. Diese Konvertierung behält immer den Wert bei.

Wenn ein Typ, der kleiner als eine Ganzzahl ist, in einer mathematischen Operation verwendet wird, wird er in eine Ganzzahl konvertiert. Dies ist die Ursache für den negativen Wert im zweiten Fall - die Operanden werden vor der Subtraktion in int konvertiert und erzeugen als Ergebnis einen negativen Wert. Es mag einfacher sein, diesen bestimmten Ausdruck als ((int)y - (int)x) zu betrachten, was deutlich macht, dass es negativ sein darf.

0

Beachten Sie, dass y - x negativ ist. Der Typ ist immer noch unsigned short/int. Sie neigen dazu, in diesem Fall anstelle von negativen Zahlen ein Zweierkomplement zu erhalten, was anders ist, weil sizeof (short) und sizeof (int) für Sie unterschiedlich sind.

denke ich, was Sie wirklich gemeint

float f1(unsigned int x, unsigned int y)      
{                
    float val;            
    val = float(float(y) - x)/(y + x);         
    return val;            
} 
+0

im 'unsigned short' Fall, der Typ von 'y-x' ist' int' (falls 'sizeof (int)> sizeof (short) ') aufgrund von Integer-Promotions –

0

In Ausdruck

y-x 

Objekte x und y vom Typ unsigned short gefördert werden int aufgrund der Integer-Förderung zu geben. Sie können es sich vorstellen, wie

(int)y - (int) x 

Und wenn y weniger als x dann wird das Ergebnis negativ sein.

Wenn x und y vom Typ unsigned int sind, dann hat das Ergebnis auch den Typ unsigned int.

0

Es ist, weil y kleiner als x: y-x kleiner als 0 ist, und Sie verwenden unsigned int und unsigned short, so dass sie ‚umgerechnet‘ in positive Zahlen, entsprechend ihrer maximale Reichweite, die differents sind.