C: performing signed comparison in unsigned variables without casting
i want a function with the following signature:
bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b);
its output should be 1
iff the 2's-complement view of the bits stored in a
is greater than the 2's complement view of the bits stored in b
. otherwise the output should be 0
. for example:
signed_a_greater_than_signed_b(0b10000000,any number) =>开发者_Python百科 0
signed_a_greater_than_signed_b(0b01111111,any number other than 0b01111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000001) => 0
signed_a_greater_than_signed_b(0b00000000,0b11111111) => 1
signed_a_greater_than_signed_b(0b00000000,0b00000000) => 0
the function is not to have any implicit/explicit conversions (as these conversions are implementation-defined, and thus not portable)
one such implementation is:
bool signed_a_greater_than_signed_b(unsigned char a, unsigned char b)
{
// if 'signed' a is positive then
// return 1 if a is greater than b or b is negative
// otherwise, if 'signed' a is negative then
// return 1 if a is greater than b and b is negative
if (a <= 0b01111111) return ((b < a) || (b > 0x01111111));
else return ((b < a) && (b > 0x01111111));
}
can you suggest an implementation that uses arithmetic rather than conditionals to perform this calculations? you may use one condition if you must
using a mix of un/signed variables in comparisons and arithmetic in C is a recipe for disaster. this function is an example of how to circumvent the problem.
i guess the assembly behind comparison of signed variables is similar to the function i want to implement (on architectures not supporting signed comparisons)
Assuming 2's complement:
return (a^signbit) > (b^signbit);
where signbit
is obviously the MSB of the representation.
you may use one condition if you must
You already have a solution using only one condition. ;)
As you would like to have arithmetic operations rather than conditionals, I assume that the goal is speed. And using a look-up table is even faster than arithmetic. Because you are using 8 bit chars, a look-up table means no overkill: You don't even need a table of size 256x256. A table size of 256 is perfectly adequate storing a limit for each value of a
indicating the value(s) b
may have to result in true (or false). Each function call only needs to perform one table look-up (a
-> limit
) and one comparison (limit
<> b
).
精彩评论