Envoyé par
ducon
Avec une valeur absolue.
max(a,b)=(a+b+|a−b|)/2.
min(a,b)=(a+b−|a−b|)/2.
Pour comprendre, faites un dessin et placer le milieu (a+b)/2, auquel vous ajoutez ou vous soustrayez la moitié de la distance entre a et b, à savoir |a−b|/2. Ensuite, on factorise.
Alors il faut trouver la valeur absolue sans faire de test. (je viens de regarder le code de abs() dans la DLL de Windows, elle utilise un branchement)
En fait si on sait que l'ordinateur a au moins un Pentium 2 on peut utiliser le jeu d'instructions prévu pour ça, ça donne un truc du genre :
Code:
; On stocke dans ECX le nombre le plus grand entre EAX et EBX
mov ecx, eax
cmp eax, ebx
cmovb ecx, ebx
Sinon on peut chipoter avec un booléen qui représente le résultat d'une condition (si le compilateur est malin il utilise SETCC) et un masque pour avoir le bon résultat. Je laisse encore un peu chercher.
Avec ta solution on peut faire comme ça :
Code:
int a, b, abs, max;
int const masque = (a-b) >> 31;
abs = a - b;
abs = (abs ^ masque) - masque;
max = (a + b + abs) / 2;
A part le fabs du FPU je ne connais pas d'autre moyen de trouver la valeur absolue.