问题
I'm working on a high speed computing problem for a large scale simulation. In order to speed up the process I wish to make a couple of optimizations, one of which is to compute the absolute value of a double in only a couple of cycles without jumps.
My idea was, that 64-Bit double values are represented with a 1-Bit sign Bit, an 11-Bit exponent and a 52-Bit Mantissa. So a double value XOR-ed with a mask: 10000000 00000000 00000000 00000000 would yield the desired result:
double abs(double x) {
double mask = -0.0e0;
return x^mask;
}
Now obviously there are few reason one would need binary operations on doubles, so naturally the compiler throws an error:
error: invalid operands to binary ^ (have ‘double’ and ‘double’)
I was wondering whether there was any way to make this work in a fast fashion, since I didn't wish to convert the whole thing into a char-array and back as was suggested elsewhere. That would sort of defeat the purpose of fast computing.
I'm thankful for all help...
回答1:
Variation on @Artur:
.. Use matching sized integer.
.. Initialize union with double. Not faster, but tighter.
#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'd stay with fabs() unless profiling showed other solutions faster.
回答2:
Have not checked but this should do the job:
double abs(double x)
{
long long tmp = *((long long*)&x);
tmp &= ~(1LL << 63);
return *((double*)&tmp);
}
Update:
Users commenting my solution were right about problems with 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;
}
回答3:
double x;
int *p = (int *)&x;
*(p+1) ^= (1 << 31);
来源:https://stackoverflow.com/questions/20458125/binary-operations-on-doubles-in-c