在 C# 中否定浮点值的最佳方法

Optimal way to negate a floating point value in C#

从代码执行的角度来看什么更快:

double a = 1.234;
double minus_a = -a;

或:

double a = 1.234;
double minus_a = a * -1;

第二种情况真的执行浮点乘法吗?或者编译器是否足够聪明,可以将第二种情况优化为与第一种情况相同?

使用 .NET 4 的 64 位 JIT 进行测试,其他 JIT,例如旧的 32 位 JIT 或较新的 RyuJIT 可能不同(实际上 32 位旧 JIT 必须 做其他事情因为它不使用 SSE),尽管 64 位核心 CLR 5.0 仍然做同样的事情。

-x 转化为

vmovsd      xmm1,qword ptr [00000050h] ; the constant is -0.0, so only the sign bit is set
vxorpd      xmm0,xmm0,xmm1 ; literally flip the sign

x * -1变成

vmulsd      xmm0,xmm0,mmword ptr [00000048h] ; -1.0

是的,非常直白。

至于速度,您可以从 here 中选择您的模型并进行比较,但是 vxorpd 总是比 vmulsd 快。

是否可以将 x * -1 优化为 XOR?可能是。有一些古怪的情况下它不会做同样的事情,例如当 DAZ or FTZ are set (它们影响 vmulsd 在非规范值的情况下的操作,但 vxorps 忽略这些标志,它始终是纯异或)。但是在 .NET 中没有使用这些功能的官方方法。