首页 > 解决方案 > 这些函数有什么作用?

问题描述

我从其他人编写的代码中找到了以下两个函数,但我真的不明白这些函数的作用。

typedef  union
{
    t_float f; //float
    unsigned int ui;
}t_bigorsmall32;

static inline int PD_BADFLOAT(t_float f)  /* malformed float */
{
    t_bigorsmall32 pun;
    pun.f = f;
    pun.ui &= 0x7f800000;
    return((pun.ui == 0) | (pun.ui == 0x7f800000));
}

static inline int PD_BIGORSMALL(t_float f)  /* exponent outside (-64,64) */
{
    t_bigorsmall32 pun;
    pun.f = f;
    return((pun.ui & 0x20000000) == ((pun.ui >> 1) & 0x20000000));
}

如果有人能解释他们的工作,我将不胜感激。而且我还想知道是否有来自标准库或 C++ 的内置替代函数。

标签: c

解决方案


很容易看出,代码通过联合类型双关将字节IEEE 754 binary32 float重新解释为 32 位无符号整数。然后它使用逐位运算来检查浮点数指数中的特定位。了解它的实际作用需要对 binary32 存储格式有复杂的了解。


PD_BADFLOAT检查偏置指数是 0 还是最大值 255,因为0 和 255 具有特殊含义(指数为 0 的那些是次正规数和零;而 255 表示 NaN 和无穷大)。但是请注意,这些不是糟糕的浮点数- 但它们的行为也不像常规数字。


第二个检查无偏指数是否超出范围 [-63, 65] (描述似乎是错误的边界)意味着它的大小高于 2⁶⁵ (~ 3.7 * 10¹⁹) 或低于 2⁻⁶³, ( ~ 1.08 * 10⁻¹⁹)。

所有这些都是非常特定于实现且不可移植的——似乎这些都是在考虑速度的情况下进行编程的。


前者完全等同于标准宏的否定isnormal

对于后者,我认为可移植的方法是使用 C99+ 函数frexpf从 中获取指数float,然后与所需的限制进行比较,或者仅构造表示这些值的常量并将绝对值与这些限制进行比较。

因此像

static inline int PD_BADFLOAT(float f) {
    return !isnormal(f);
}

static inline int PD_BIGORSMALL(float f) {
    int exp;
    if (isnormal(f)) {
        frexpf(f, &exp);
        return exp < -63 || exp > 65;
    }

    // return 1 for subnormal numbers and
    // NaN, INF...
    return 1;
}

推荐阅读