3
votes

The following program gives a signed/unsigned mismatch warning:

#include <iostream>

int main()
{
unsigned int a = 2;
int b = -2;

if(a < b)
    std::cout << "a is less than b!";

return 0;
}

I'm trying to understand the problem when it comes to mixing signed and unsigned ints. From what I have been told, an int is typically stored in memory using two's complement.

So, let's say I have the number 2. Based on what I understand it will be represented in memory like this:

00000000 00000000 00000000 00000010

And -2 will be represented as the one's compliment plus 1, or:

11111111 11111111 11111111 11111110

With two's compliment there is no bit reserved for the sign like the "Sign-and-magnitude method". If there is no sign bit, why are unsigned ints capable of storing larger positive numbers? What is an example of a problem which could occur when mixing signed/unsigned ints?

5
Yeah, I just avoided answering this Q because of the -1 storm. Down voter please explain...Andrew White
@AndrewWhite, probably a troll seeing as how no explanation is given.chris
Whoa - why all the down votes???mathematician1975
@mathematician1975 What downvotes? Ah, in the answers. Those are totally justified.Konrad Rudolph

5 Answers

6
votes

I'm trying to understand the problem when it comes to mixing signed and unsigned ints.

a < b

By the usual arithmetic conversions b is converted to an unsigned int, which is a huge number > a.

Here the expression a < b is the same as:

2U < (unsigned int) -2 which the same as:

2U < UINT_MAX - 1 (in most two's complement systems) which is 1 (true).

With two's compliment there is no bit reserved for the sign like the "Sign-and-magnitude method".

In two's complement representation if the most significant bit of a signed quantity is 1, the number is negative.

1
votes

What would be the representation of 2 147 483 648 be?

10000000 00000000 00000000 00000000

What would be the representation of -2 147 483 648 be?

10000000 00000000 00000000 00000000

The same! Hence, you need a convention to know the difference. The convention is that the first bit is still used to decide the sign, just not using the naïve sign-magnitude method you would otherwise use. This means every positive number starts with 0, leaving only 31 bits for the actual number. This gives half the positive range of unsigned numbers.

This problem with your code is that the signed integer will be converted to unsigned. For example, -1 will become 4 294 967 295 (they have the same binary representation), and will be much larger than zero, instead of smaller. This is probably not what you expect.

0
votes

An int can only store 2^32 different values (if it's 32bit), whether it is signed or unsigned. So a signed int has 1/2 of that range below zero, and 1/2 of that range above zero. An unsigned int has that full range above zero.

While they don't call the most significant bit of a signed int a 'sign bit', it can be treated that way.

0
votes

Isnt this as easy as (int)a < int(b)??? Isnt C++ like you need to strongly do explicit type casting?

-2
votes

Well, the -1 as signed int is -1 and as unsigned int is 65534, so the problem is with signed values where "-" is required. In case of returning -1 error code, with unsigned int that would be 65534 code.