Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What will happen if I assign negative value to an unsigned char?

Tags:

c

c++11

unsigned

In C++ primer it says that "if we assign an out of range value to an object of unsigned type the result is the remainder of the value modulo the number of values the target type can hold."

It gives the example:

int main(){


unsigned char i = -1;
// As per the book the value of i is 255 .
}

Can anybody please explain it to me how this works.

like image 948
vyasriday Avatar asked Dec 22 '16 06:12

vyasriday


People also ask

What happens when you set an unsigned type to a negative value?

You simply cannot assign a negative value to an object of an unsigned type. Any such value will be converted to the unsigned type before it's assigned, and the result will always be >= 0.

Can char hold negative value?

Char is an unsigned type and cannot represent a negative value. In any case, you should not use Char to hold numeric values.

What would happen if a negative value of signed integer is casted to an unsigned integer?

It will show as a positive integer of value of max unsigned integer - 4 (value depends on computer architecture and compiler).

Can unsigned bits be negative?

Variables such as integers can be represent in two ways, i.e., signed and unsigned. Signed numbers use sign flag or can be distinguish between negative values and positive values. Whereas unsigned numbers stored only positive numbers but not negative numbers.


3 Answers

the result is the remainder of the value modulo the number of values the target type can hold

Start with "the number of values the target type can hold". For unsigned char, what is this? The range is from 0 to 255, inclusive, so there are a total of 256 values that can be represented (or "held").

In general, the number of values that can be represented in a particular unsigned integer representation is given by 2n, where n is the number of bits used to store that type.

An unsigned char is an 8-bit type, so 28 == 256, just as we already knew.

Now, we need to perform a modulo operation. In your case of assigning -1 to unsigned char, you would have -1 MOD 256 == 255.

In general, the formula is: x MOD 2n, where x is the value you're attempting to assign and n is the bit width of the type to which you are trying to assign.

More formally, this is laid out in the C++11 language standard (§ 3.9.1/4). It says:

Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.*

* This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

Perhaps an easier way to think about modulo arithmetic (and the description that you'll most commonly see used) is that overflow and underflow wrap around. You started with -1, which underflowed the range of an unsigned char (which is 0–255), so it wrapped around to the maximum representable value (which is 255).

like image 127
Cody Gray Avatar answered Oct 19 '22 23:10

Cody Gray


It's equivalent in C to C++, though worded differently:

6.3.1.3 Signed and unsigned integers

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented by the new type until the value is in the range of the new type.

3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

like image 37
user3553031 Avatar answered Oct 20 '22 01:10

user3553031


The literal 1 is of type int. For this explanation, let's assume that sizeof(int) == 4 as it most probably is. So then 1 in binary would look like this:

00000000 00000000 00000000 00000001 

Now let's apply the unary minus operator to get the -1. We're assuming two's complement is used as it most probably is (look up two's complement for more explanation). We get:

11111111 11111111 11111111 11111111

Note that in the above numbers the first bit is the sign bit.

As you try to assign this number to unsigned char, for which holds sizeof(unsigned char) == 1, the value would be truncated to:

11111111

Now if you convert this to decimal, you'll get 255. Here the first bit is not seen as a sign bit, as the type is unsigned.

like image 37
DeiDei Avatar answered Oct 19 '22 23:10

DeiDei