Compare 2 floats by their bitwise representation in C

209 Views Asked by At

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 ___________________________;
}
1

There are 1 best solutions below

2
Eric Postpischil On BEST ANSWER

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