C# 中求反浮点值的最佳方法

Arv*_*ind 2 c# point negation floating

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

double a = 1.234;
double minus_a = -a;
Run Code Online (Sandbox Code Playgroud)

或者:

double a = 1.234;
double minus_a = a * -1;
Run Code Online (Sandbox Code Playgroud)

第二种情况实际上执行浮点乘法吗?或者编译器是否足够聪明,可以优化第二种情况以使其与第一种情况相同?

har*_*old 6

使用.NET 4的64位JIT进行测试,其他JIT(例如旧的32位JIT或较新的RyuJIT)可能不同(实际上32位旧的JIT必须做其他事情,因为它不使用SSE),尽管64位Core 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
Run Code Online (Sandbox Code Playgroud)

x * -1进入

vmulsd      xmm0,xmm0,mmword ptr [00000048h] ; -1.0
Run Code Online (Sandbox Code Playgroud)

是的,非常字面意思。

至于速度,你可以从这里选择你的模型并进行比较,但vxorpd总是会比 快vmulsd

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