简体   繁体   中英

unsigned int vs unsigned short difference in c++

I have the following:

#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;                                                
}                                                            

On the output I get two different values from f1 and f2 although I expect the outputs to be the same since the functions are similar. Can you please explain the source of difference?

While since both functions use unsigned values one might think that the subtraction would result in a positive number for both values, one would be wrong because of the integral promotion that takes place before evaluation of operator arithmetic for numeric types.

cppreference describes arithmetic operator conversions:

If the operand passed to an arithmetic operator is integral or unscoped enumeration type, then before any other action (but after lvalue-to-rvalue conversion, if applicable), the operand undergoes integral promotion. If an operand has array or function type, array-to-pointer and function-to-pointer conversions are applied. ...

Integral promotion is where this conversion takes place. On that subject, cppreference states the following:

Prvalues of small integral types (such as char) may be converted to prvalues of larger integral types (such as int). In particular, arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value.

Thus, if a type smaller than an integer is used in a mathematical operation, it's converted to an integer. This is the cause of the negative value in the second case--the operands are converted to int before the subtraction and produce a negative value as a result. It may be easier to look at that particular expression as ((int)y - (int)x) , which makes it apparent that it is allowed to be negative.

Note that y - x is negative. It's type is still unsigned short / int. You tend to get 2's complement instead of negative numbers in this case, which is different because sizeof(short) and sizeof(int) are different for you.

I think what you really meant is

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

In expression

y-x

objects x and y of type unsigned short are promoted to type int due to the integer promotion. You can imagine it like

( int )y - ( int ) x

And if y is less than x then the result will be negative.

When x and y are of type unsigned int then the result also has the type unsigned int .

这是因为y小于xyx小于0,并且使用unsigned int和unsigned short,因此根据它们的最大范围(它们是不同的)将它们“转换”为正数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM