Search code examples
c#pointfloatingnegation

Optimal way to negate a floating point value in C#


What is faster from a code execution perspective:

double a = 1.234;
double minus_a = -a;

or:

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

Does the second case actually perform floating point multiplication? Or is the compiler smart enough to optimize the second case to be the same as the first?


Solution

  • Tested with the 64bit JIT of .NET 4, other JITs such as the old 32bit JIT or the newer RyuJIT can be different (actually the 32bit old JIT must do something else since it does not use SSE), though 64bit Core CLR 5.0 still does the same thing.

    -x translates into

    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 into

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

    Yes, very literal.

    As for speed, you can pick your model from here and compare, but vxorpd will always be faster than vmulsd.

    Could it have optimized x * -1 to a XOR? Maybe. There are some quirky cases in which that does not do the same thing, eg when DAZ or FTZ are set (they affect the operation of vmulsd in the case of denormal values, but vxorps ignores those flags, it's always a pure xor). But there is no official way to use those features in .NET.