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