Fastest way to flip the sign of a double / float in C

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

Answers


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

.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

It should be noted that xorps is XOR designed for floatin points, taking care of special conditions. It's a SSE instruction.


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.


If you want portable way, just multiply by -1 and let compiler optimise it.


Need Your Help

How to signal select() to return immediately?

c multithreading select sockets

I have a worker thread that is listening to a TCP socket for incoming traffic, and buffering the received data for the main thread to access (let's call this socket A). However, the worker thread a...

What does a single "throw;" statement do?

c++ exception throw

These days, I have been reading a lot the C++ F.A.Q and especially this page.