-5

Following are different programs/scenarios using unsigned int with respective outputs. I don't know why some of them are not working as intended.

Expected output: 2

Program 1:

int main()
{
    int value = -2;
    std::cout << (unsigned int)value;

    return 0;
}

// OUTPUT: 4294967294

Program 2:

int main()
{
    int value;
    value = -2;
    std::cout << (unsigned int)value;

    return 0;
}

// OUTPUT: 4294967294

Program 3:

int main()
{
    int value;
    std::cin >> value; // 2
    std::cout << (unsigned int)value;

    return 0;
}

// OUTPUT: 2

Can someone explain why Program 1 and Program 2 don't work? Sorry, I'm new at coding.

whaaaaaaat
  • 7
  • 2
  • 3

2 Answers2

2

You are expecting the cast from int to unsigned int to simply change the sign of a negative value while maintaining its magnitude. But that isn't how it works in C or C++. when it comes to overflow, unsigned integers follow modular arithmetic, meaning that assigning or initializing from negatives values such as -1 or -2 wraps around to the largest and second largest unsigned values, and so on. So, for example, these two are equivalent:

unsigned int n = -1;
unsigned int m = -2;

and

unsigned int n = std::numeric_limits<unsigned int>::max();
unsigned int m = std::numeric_limits<unsigned int>::max() - 1;

See this working example.

Also note that there is no substantial difference between programs 1 and 2. It is all down to the sign of the value used to initialize or assign to the unsigned integer.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • thanks for the reply, so then why does it remove the sign when I input the value in program 3? – whaaaaaaat Jul 17 '15 at 06:14
  • @whaaaaaaat An unsigned integer can only be positive. What I describe is what happens when you initialize or assign from a negative number. – juanchopanza Jul 17 '15 at 06:16
  • I see a down-vote. If I made a mistake or anything is unclear I'd be interested in knowing so I can fix it. – juanchopanza Jul 17 '15 at 06:17
0

Casting a value from signed to unsigned changes how the single bits of the value are interpreted. Lets have a look at a simple example with an 8 bit value like char and unsigned char.

The values of a character value range from -128 to 127. Including the 0 these are 256 (2^8) values. Usually the first bit indicates wether the value is negativ or positive. Therefore only the last 7 bits can be used to describe the actual value.

An unsigned character can't take any negative values because there is no bit to determine wether the value should be negative or positiv. Therfore its value ranges from 0 to 256.

When all bits are set (1111 1111) the unsigned character will have the value 256. However the simple character value will treat the first bit as an indicator for a negative value. Sticking to the two's complement this value will be -1.

This is the reason the cast from int to unsigned int does not what you expected it to do, but it does exactly what its supposed to do.

EDIT

If you just want to switch from negative to positive values write yourself a simple function like that

uint32_t makeUnsigned(int32_t toCast)
{
    if (toCast < 0)
        toCast *= -1;
    return static_cast<uint32_t>(toCast);
}

This way you will convert your incoming int to an unsigned int with an maximal value of 2^32 - 1

muXXmit2X
  • 2,745
  • 3
  • 17
  • 34