Opérations binarys sur les doubles en C

Je travaille sur un problème informatique à grande vitesse pour une simulation à grande échelle. Afin d’accélérer le processus, je souhaite effectuer deux optimisations, dont l’une consiste à calculer la valeur absolue d’un double en seulement deux cycles sans sauts.

Mon idée était que les valeurs doubles 64 bits sont représentées par un bit de signe 1 bit, un exposant 11 bits et une mantisse 52 bits. Donc, une valeur double XOR-ed avec un masque: 10000000 00000000 00000000 00000000 donnerait le résultat souhaité:

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

Maintenant, évidemment, il y a peu de raisons pour lesquelles on aurait besoin d’opérations binarys sur les doublons, alors naturellement, le compilateur renvoie une erreur:

 error: invalid operands to binary ^ (have 'double' and 'double') 

Je me demandais s’il y avait un moyen de faire cela rapidement, puisque je ne souhaitais pas convertir le tout en tableau de caractères et inversement, comme suggéré ailleurs. Cela irait à l’encontre du but de l’informatique rapide.

Je suis reconnaissant pour toute aide …

Variation sur @Artur:
.. Utilisez un entier de taille correspondante.
.. Initialise l’union avec double. Pas plus vite, mais plus serré.

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

Remarque: je restrais avec les fabs() moins que le profilage indique d'autres solutions plus rapidement.

Je n’ai pas vérifié, mais cela devrait faire le travail:

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

Mettre à jour:

Les utilisateurs qui commentaient ma solution avaient raison sur les problèmes liés au code ci-dessus. Cela devrait être mieux:

 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; } 
 double x; int *p = (int *)&x; *(p+1) ^= (1 << 31);