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

我认为,直接访问符号位将是最快的方法,并发现了以下内容:

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有点。您应该对其进行XOR。无论如何,这就是我测试过的编译器(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是针对floatin点进行XOR设计的,并要考虑特殊条件。这是SSE指令。

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

10-11 05:05