In Jens Gustedt's book Modern C, on page 59, he explains how signed integers can be emulated using unsigned integers. His example code shows how one can implement a comparison of two unsigned integers reinterpreted as signed integers:
bool is_negative(unsigned a) {
unsigned const int_max = UINT_MAX /2;
return a > int_max;
}
bool is_signed_less(unsigned a, unsigned b) {
if (is_negative(b) && !is_negative(a)) return false;
else return a < b;
}
Do I misunderstand something here or does he miss the second special case where is_negative(a) = true and is_negative(b) = false?
For example if we want to have a = -1 and b = 1, then, using two's complement, we would represent them as
unsigned int a = UINT_MAX;
unsigned int b = 1;
(e.g. for a 4 bit integer we would have a = 1111 and b = 0001).
Now we have is_negative(a) returns true, and is_negative(b) returns false. When calling is_signed_less(a, b) we end up in the else clause and a < b (now interpreted as unsigned integers) will return false. However, it is clearly true that -1 < 1, so the function returns the wrong result.
Is this a typo in the code of the book or is there something that I do not understand?
return a < bsuffices. When signs differ,return a > bshould apply.#define Offset (UINT_MAX/2+1)/bool is_signed_less(unsigned a, unsigned b) { return a+Offset < b+Offset; }.