在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/