在 C 中翻转 double / float 符号的最快方法
在 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
What is the fastest way to flip the sign of a double (or float) in C?
I thought, that accessing the sign bit directly would be the fastest way and found the following:
double a = 5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0
float b = 3.0;
*(int*)&b |= 0x80000000;
// b = -3.0
However, the above does not work for negative numbers:
double a = -5.0;
*(__int64*)&a |= 0x8000000000000000;
// a = -5.0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您只是在前面添加一个否定运算符,即
-a
,任何像样的编译器都会实现此位操作。不管怎样,你正在对这个位进行“或”运算。你应该对其进行异或。这就是我测试的编译器(GCC、MSVC、CLang)所做的事情。因此,帮自己一个忙,写一下-a
编辑:请注意,C 不强制执行任何特定的浮点格式,因此对非整数 C 变量的任何位操作最终都会导致错误行为。
由于评论而编辑 2:这是 GCC 为 x86_64 发出的否定代码。
应该注意的是,
xorps
是为浮点数设计的 XOR,照顾特殊条件。这是一条 SSE 指令。Any decent compiler will implement this bit manipulation if you just prepend a negation operator, i.e.
-a
. Anyway, you're OR-ing the bit. You should XOR it. This is what the compilers I tested it do anyway (GCC, MSVC, CLang). So just do yourself a favour and write-a
EDIT: Be aware that C doesn't enforce any specific floating point format, so any bit manipulations on non-integral C variables will eventually result in errornous behaviour.
EDIT 2 due to a comment: This is the negation code GCC emits for x86_64
It should be noted that
xorps
is XOR designed for floatin points, taking care of special conditions. It's a SSE instruction.a=-a
a=-a
此代码未定义,因为它违反了严格的别名规则。
什么是严格别名规则?
要明确定义这一点,您必须依赖编译器为您优化它。
This code is undefined since it violates the strict aliasing rule.
What is the strict aliasing rule?
To do this well defined you will have to rely on the compiler optimizing it for you.
如果你想要可移植的方式,只需乘以
-1
并让编译器优化它。If you want portable way, just multiply by
-1
and let compiler optimise it.