I had this question on my exam, and I couldn't realy solve it, will appreciate some help.
Fill the blanks only, function must return true if and only if x<y. Assume x,y cannot be NaN (but can be +-inf) no casting is allowed, use only ux, uy, sx, sy
bool func(float x, float y) {
unsigned* uxp = ______________ ;
unsigned* uyp = ______________ ;
unsigned ux = *uxp;
unsigned uy = *uyp;
unsigned sx = (ux>>31);
unsigned sy = (uy>>31);
return ___________________________;
}
Presumably the assignment assumes float
uses IEEE-754 binary32 and unsigned
is 32 bits.
It is not proper to alias float
objects with an unsigned
type, although some C implementations support it. Instead, you can create a compound literal union, initialize its float
member with the float
value, and access its unsigned
member. (This is supported by the C standard but not by C++.)
After that, it is simply a matter of dividing the comparison into cases depending on the sign bits:
#include <stdbool.h>
bool func(float x, float y) {
unsigned* uxp = & (union { float f; unsigned u; }) {x} .u;
unsigned* uyp = & (union { float f; unsigned u; }) {y} .u;
unsigned ux = *uxp;
unsigned uy = *uyp;
unsigned sx = (ux>>31);
unsigned sy = (uy>>31);
return
sx && sy ? uy < ux : // Negative values are in "reverse" order.
sx && !sy ? (uy | ux) & 0x7fffffffu : // Negative x is always less than positive y except for x = -0 and y = +0.
!sx && sy ? 0 : // Positive x is never less than negative y.
ux < uy ; // Positive values are in "normal" order.
}
#include <stdio.h>
int main(void)
{
// Print expected values and function values for comparison.
printf("1, %d\n", func(+3, +4));
printf("1, %d\n", func(-3, +4));
printf("0, %d\n", func(+3, -4));
printf("0, %d\n", func(-3, -4));
printf("0, %d\n", func(+4, +3));
printf("1, %d\n", func(-4, +3));
printf("0, %d\n", func(+4, -3));
printf("1, %d\n", func(-4, -3));
}
Sample output:
1, 1 1, 1 0, 0 0, 0 0, 0 1, 1 0, 0 1, 1