c - 在 C 中翻转 double /浮点符号的最快方法

标签 c floating-point double bit-manipulation sign

在 C 中翻转 double (或 float )符号的最快方法是什么?

我想,直接访问符号位是最快的方法,结果发现如下:

double a = 5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0

float b = 3.0;
*(int*)&b |= 0x80000000;
// b = -3.0

但是,以上不适用于负数:

double a = -5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0

最佳答案

如果您只是在前面加上一个否定运算符,即 -a,任何体面的编译器都会实现这种位操作。无论如何,您正在对位进行 OR-ing。你应该异或它。这就是我测试过的编译器无论如何都会做的事情(GCC、MSVC、CLang)。所以,帮自己一个忙,写 -a

编辑:请注意 C 不强制执行任何特定的浮点格式,因此对非整数 C 变量的任何位操作最终都会导致错误行为。


根据评论编辑 2:这是 GCC 为 x86_64 发出的否定代码

.globl neg
    .type   neg, @function
neg:
.LFB4:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movss   %xmm0, -4(%rbp)
    movss   -4(%rbp), %xmm1
    movss   .LC0(%rip), %xmm0
    xorps   %xmm1, %xmm0  /* <----- Sign flip using XOR */
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE4:
    .size   neg, .-neg

需要注意的是,xorps 是专为 float 设计的 XOR,用于处理特殊情况。这是一条 SSE 指令。

关于c - 在 C 中翻转 double /浮点符号的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5213338/

相关文章:

c++ - 在 C++ 中找到最小值(双)

c - 为什么在位溢出的情况下丢弃 MSB?

c - printf 语句中 % 符号在以下情况下的作用

c - Eclipse:用 C 创建 Hello World 应用程序

c++ - C++ 中的整数溢出和整数乘法

c++ - Float64 转字符串

c++ - 如何进行带有偏差的浮点舍入(总是向上或向下舍入)?

c - 四舍五入以避免在随后的求和中四舍五入

opencv:执行在图像像素访问的双指针算法处停止

c - 为什么我的指针数组返回一个 unicode 字符?