Binary double operations in C

I am working on the problem of high-speed computing for large-scale modeling. To speed up the process, I want to make a couple of optimizations, one of which is to calculate the absolute value of the double in just a couple of cycles without transitions.

My idea was that 64-bit binary values ​​are represented by a 1-bit bit, an 11-bit metric, and a 52-bit Mantissa. So, the double value of XOR-ed with mask: 10000000000000000000000000000000 will give the desired result:

double abs(double x) {
    double mask = -0.0e0;
    return x^mask;
}

Now, obviously, there are few reasons why double operations in doubles are needed, therefore, of course, the compiler throws an error:

error: invalid operands to binary ^ (have β€˜double’ and β€˜double’)

I was wondering if there is a way to quickly make this work, since I did not want to convert all this to a char -array and vice versa, as suggested elsewhere. This can undermine the goal of quick calculation.

I am grateful for the help ...

-1
source share
3 answers

Change to @Artur:
.. Use a suitable integer size.
.. Initialize the union with a double. Not faster, but stronger.

#include <stdint.h>
double Abs_double(double d) {
  union {
    double d;
    uint64_t u64;
  } u = {d};
  u.u64 &= ~( (uint64_t) 1 << 63);
  return u.d;
}

Note. I would stay with fabs()if profiling did not show other solutions faster.

+2
source

Not verified, but this should complete the task:

double abs(double x) 
{
    long long tmp = *((long long*)&x);
    tmp &= ~(1LL << 63);
    return *((double*)&tmp);
}

Update:

Users commenting on my decision were right about problems with the above code. This should be better:

double my_abs(double x) 
{
    union my64bits
    {
        unsigned long long a;  
        double             b;  
    };

    union my64bits tmp;
    tmp.b = x;
    tmp.a &= ~(1uLL<<63);

    return tmp.b;
}
+1
source
double x;
int *p = (int *)&x;
*(p+1) ^= (1 << 31);
-3
source

All Articles