In K&R ANSI C book, section A.7.4.5 (Unary Minus Operator) it is stated:
... The negative of an unsigned quantity is computed by subtracting the promoted value from the largest value of the promoted type and adding one; ...
How exactly is this calculated? Could you give a short C example?
I don't see how this could yield the negative of, say, 200u: subtracting 200 from a max value of any integral type (signed or unsigned) and adding 1 does not result in -200.
I know what the Unary minus does - the problem is that I don't see how the result is calculated according to the description.
Unsigned values can't be negative, so -200 is not a possible result.
What it's saying is that if UINT_MAX
is 65535 on your system, then the result of:
unsigned a = 200;
unsigned b = -a;
long c = -a;
will leave 65336 in both b
and c
.
If your system has UINT_MAX > LONG_MAX
(typically because int
and long
are the same size), you will need to use long long
for c
(although note that there's not even any guarantees that that's long enough).
This detail (that the result of negating an unsigned number is another, necessarily positive, unsigned number) can result in some unexpected effects if you do not understand it. For example, in this code the first example prints "true"
but the second example prints "false"
:
int a = 200;
unsigned b = 200;
if (-a < 100) printf("true\n"); else printf("false\n");
if (-b < 100) printf("true\n"); else printf("false\n");
(note that we are not storing the result of the negation operator anywhere - that is not the issue).
Apparently you missed the word unsigned in the description you quoted. This is the key word in this case. In C language the "negative" of an unsigned quantity is still unsigned, meaning that it is not really negative. Unsigned values can't ever be negative, by definition. They are always positive or 0. Arithmetic of unsigned values in C is modulo arithmetic or, in simple words, unsigned quantities "wrap around" when you perform arithmetical operations on them. Unary negation is not an exception. Calculating -n
when n
is unsigned is no different from calculating 0 - n
. If n
is unsigned int
and its value is 200
the expected result is not -200
, but rather UINT_MAX - 200 + 1
, which is exactly what the quote is telling you.
It describes operations to implement modular arithmetic, i.e. it computes a value such that
a + (-a) == 0
This makes the negated unsigned number behave closely to a negated signed number.
On machines where the number representation is two's complement (such as x86), this is done by just treating the bit pattern of the unsigned number as an ordinary signed number, and using the machine's standard "negate" instruction.
Another question has touched this topic already
Example
unsigned char i = -10;
printf("%u\n",i);
Result
246
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With