在C中翻转双/浮点符号的最快方法

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

我想,直接访问符号位将是最快的方法,并找到以下内容:

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 ,那么任何体面的编译器都会实现这种位操作。 无论如何,你正在努力。 你应该对它进行异或。 这就是我测试它的编译器所做的事情(GCC,MSVC,CLang)。 所以,请自己帮个忙,写一下

编辑:请注意,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是针对xorps设计的XOR,可以处理特殊情况。 这是一个SSE指令。

a=-a

此代码未定义,因为它违反了严格的别名规则。 什么是严格别名规则? 为了做到这一点,你必须依靠编译器为你优化它。

如果你想要可移植的方式,只需乘以-1 ,让编译器优化它。