Optimiser la fonction "valeur absolue" en C++/PC

Hello,

Sauriez-vous si il y a un moyen d’écrire une fonction “valeur absolue” optimisée, avec mettons une ou deux instructions simples et sans embranchement conditionnel (if, “?:” …)
J’écris un algo assez lourd qui utilise beaucoup de valeurs absolues et je voudrais voir si y’a pas moyen de gagner quelques précieuses millisecondes par boucle.
Le truc aussi, si possible, ce serait d’avoir une macro qui fonctionne quel que soit le type signé (char, short, long, float)
Je me prends la tête depuis ce matin pour chercher quelque chose avec les différents opérateurs binaires disponibles mais je trouve pas…
excepté le bricolage suivant : (x < 0) && (x = -x); mais c’est moyen car il me semble que C++ n’impose par d’ordre d’opérations avec l’opérateur && (ici, l’ordre voulu est de gauche à droite) , ça dépend alors du compilo. [edit : d’ailleurs je sais pas comment ca se traduit en code machine, ça revient peut-etre à un embranchement conditionnel]
Edité le 07/09/2007 à 12:05

Bonjour,

Oui, c’est pas parce que le code est plus “compact” qu’il est plus rapide: que le if soit caché ou pas, il est fait.

à priori, le “abs” est déjà codé dans le FPU, donc il n’y a pas plus optimisé que le std:abs() du C++.

ils ont quand même eu pas mal d’idée sur le sujet sur ce Thread (d’un autre site) :
forum.hardware.fr…
pour calcul le abs d’un int, tu gagne le temps d’appel sur la pile…

mais si tu fait beaucoup de boucle sur des calculs, essaye plutôt de voir ce qui peut sortir de la boucle en modifiant légèrement le calcul.

Hmm bon, dans tous les cas je crois que le gain sera négligeable, mais ça a piqué mon esprit donc je cherche quand meme une réponse :slight_smile:

Sinon, autre chose : sous Visual Studio 2005, j’obtiens une erreur lorsque j’essaie de faire des opérations binaires sur un float : par exemple si je fais


float x = 2.2f;
int i = ( x & 0xf800) >> 23;

J’obtiens l’erreur error C2296: ‘&’ : non conforme, l’opérande gauche est du type ‘float’ => c’est normal?

Salut,

Il me semble que les opérateurs bit à bit ne peuvent pas s’appliquer sur des variables réelles (je vais essayer de le vérifier quand même). Dans un de mes anciens codes qui analyse un float (comment il se décompose en mémoire selon la norme IEEE754) j’ai casté un pointeur sur float en un pointeur sur char afin de le travailler avec les opérateurs bit à bit (| & ~ >> et <<).

Mais je vérifie et je te tiens au courant.

EDIT: après vérification dans un livre de Delannoy sur le C, les opérandes des opérations de bit à bit doivent être de type entier. Seule la promotion numérique peut s’appliquer.
Edité le 07/09/2007 à 22:42

Je ne sais pas si la source de mon analyseur de float t’intéresse. Si tu le veux je peux toujours t’envoyer le source par email (passe par MP).

Poste le là même.

Sinon, le bit de signe, c’est pas le premier ? Dans ce cas (((char)&x) & 0x7F non?

Oui en effet c’est le premier bit (0 = +, 1 = -). Mais encore faut-il savoir quelle type de réel on utilise (sur 80, 64 ou 80 bits?) et si c’est bien la norme IEEE754 qui est utilisée (les spécifications conseillent mais n’oblige pas d’utiliser cette norme) et surtout: si on est en petit indien ou en grand indien (comme disait mon prof :nexath).

Et sinon vous pouvez allez voir le code que j’avais fait il y a longtemps : ici (ça me semble marcher mais il y a sans-doute des choses mal codées).
Edité le 08/09/2007 à 00:04

:etonne:

Merci à tous.
En effet ça marche si je cast le pointeur float en pointeur char

:MDR
ça me laisse sans voix (et pas Sans-Nom :nexath)…
Serais-je donc un gros pervers refoulé…
Edité le 08/09/2007 à 12:16

Mais là, tu perds pas plus de temps à faire un appel à ta fonction que de faire ton branchement conditionnel? :slight_smile:

C’est pas un code qui est censé être rapide. Je n’ai jamais dit que ce code est est utile, il permet de juste de voir comment est formé un float codé avec l’IEEE754.