c - 整数与其负数按位或的目的

标签 c integer bitwise-or

我很好奇 NaN 在 IEEE 单精度和 double 浮点中的实现和表示,我发现了 this implementation一个“是 NaN”的函数。即:

int isnan(double x)
{
    int32_t hx,lx;

    // Move lower 32 bits of double to lx, higher 32 to hx.
    EXTRACT_WORDS(hx,lx,x);

    // Remove sign bit, since -NaN and NaN are both NaN.
    hx &= 0x7fffffff;

    // Equivalent to hx |= (lx != 0).
    hx |= (u_int32_t)(lx|(-lx))>>31;

    // Difference is negative iff (hx & 0x7ff00000) == 0x7ff00000 and (hx & 0x000fffff) != 0.
    hx = 0x7ff00000 - hx;
    return (int)((u_int32_t)(hx))>>31;
}

我不明白 (lx|(-lx)) >> 31 的目的,在我头脑中无法推理出来之后,我对所有整数进行了测试,发现lx = 0 结果为 0,否则为 1。

我能想到的唯一原因可能是使用 (lx != 0) 是不可能的,因为某些 C 标准没有定义分配给真正操作的整数值(例如,不是保证为 1 表示真)或者 != 可能比 negative-or-and-bit-shift 慢。否则,我很难过。

作为引用,我用来尝试所有整数的代码,以防出现错误。

#include <stdio.h>
#include <stdint.h>
int main(void) {
        int32_t i = 0;
        do {
                if (((uint32_t)(i | (-i)) >> 31) == 0)
                        printf("%d\n", i); // prints only 0
        } while (i++ != 0xFFFFFFFF); // overflows to -max_int and then climb to -1
        return 0;
}

最佳答案

表达式 (u_int32_t)(lx|(-lx))>>31 等价于 lx==0? 0:1.

然而,对于 lx==0? 0:1,您正在将分支操作强加到目标代码中。

与几个按位操作相比,这可能会降低性能。

这实际上取决于底层硬件架构以及手头指定的编译器。

但这肯定会导致性能不一致,具体取决于分支预测启发式方法。

(u_int32_t)(lx|(-lx))>>31 的运行时间在每次执行时保证相同。

关于c - 整数与其负数按位或的目的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25905263/

相关文章:

c++ - 如何拦截 GNOME 中的键盘快捷键

python - 用于在磁盘上有效存储整数对集的数据结构选项?

c - 条件语句中的按位运算符

javascript - 想知道与 0 使用 OR 位运算的原因

c - 为 x11 窗口定义自定义属性,以便将其他数据与其关联

c - c linux中的管道连接3个进程以执行命令

python - 如何在 Windows 上找到当前的系统缓存大小?

python - python 中包含整数和字符串的列表

将文件中的一组字符转换为 int

C 或 '|' 运算符