通过 C 中的按位表示比较 2 个浮点数

-1 c floating-point unsigned bit-manipulation ieee

我考试时遇到了这个问题,但我无法真正解决它,希望得到一些帮助。

仅填充空白,当且仅当 x<y 时函数必须返回 true。假设 x,y 不能为 NaN(但可以为 +-inf),不允许进行转换,仅使用 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 ___________________________;
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*hil 5

据推测,该分配假设float使用 IEEE-754 二进制32 和unsigned为 32 位。

float尽管某些 C 实现支持它,但用类型为对象别名是不正确的unsigned。相反,您可以创建一个复合文字联合,float用该值初始化其成员float,然后访问其成员unsigned成员。(C 标准支持这一点,但 C++ 不支持。)

之后,只需根据符号位将比较划分为不同的情况即可:

#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));
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

1, 1
1, 1
0, 0
0, 0
0, 0
1, 1
0, 0
1, 1