Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding signed vs unsigned comparison [duplicate]

Tags:

c++

underflow

Can somebody tell me why the if condition is false?

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int a;
    unsigned int ua;

    a = -1;
    ua = a;

    cout << "ua: " << ua << endl;
    if (ua != -1)
        cout << "Is unsigned" << endl;
    else
        cout << "Is signed" << endl;

    return 0;
}

I mean, here ua == int_max_value, it's NOT -1, but when I run this, the output is

Is signed

like image 847
harryPoker Avatar asked Aug 27 '14 02:08

harryPoker


People also ask

How do you know if its signed or unsigned?

An unsigned number contains just zero or positive values, whereas a signed number has both positive and negative numbers along with the value zero. The maximum value of signed numbers is half that of unsigned numbers.

How do you compare signed and unsigned integers?

A 1-byte unsigned integer has a range of 0 to 255. Compare this to the 1-byte signed integer range of -128 to 127. Both can store 256 different values, but signed integers use half of their range for negative numbers, whereas unsigned integers can store positive numbers that are twice as large.

What is the difference between signed and unsigned multiplication?

As far as hardware goes, unsigned multiplication and signed multiplication are exactly the same (ignoring flags). When you multiply 11111111 and 11111111 , the result is 00000001 , regardless of whether the inputs are considered to mean -1 or 255.

Can double be signed or unsigned?

You can not have unsigned floating point types. Therefore no unsigned double or unsigned float. unsigned can only be applied to integer types like char short int and long. The reason we have unsigned integers is that they can store numbers twice as large, and can be better suited for handling binary data.


2 Answers

!= and == on arithmetic types perform what is known as the usual arithmetic conversions on their operands. As relevant here, given one operand of type unsigned X and one operand of type signed X, where X is one of int, long and long long, the usual arithmetic conversions convert the signed operand to the unsigned type before the comparison takes place.

Hence, when you compare ua (of type unsigned int) and -1 (of type signed int), -1 is converted to type unsigned int (conceptually, by adding 232 to it, assuming 32-bit int), and the result compares equal to the value of ua.

like image 199
T.C. Avatar answered Oct 05 '22 23:10

T.C.


This is expected behavior, != will perform the usual arithmetic conversions on it's operands if they are arithmetic types. This is covered in the draft C++ standard section 5.10 Equality operators which says:

If both operands are of arithmetic or enumeration type, the usual arithmetic conversions are performed on both operands; each of the operators shall yield true if the specified relationship is true and false if it is false.

in this case this will lead to the integer promotion which will see -1 converted to unsigned int. This is covered in section 5 paragraph 10 which ends up saying:

Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

like image 20
Shafik Yaghmour Avatar answered Oct 05 '22 23:10

Shafik Yaghmour