Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
822 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Décomposition minimale

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Décomposition minimale

n°1292333
Chronoklaz​m
Posté le 25-01-2006 à 23:21:06  profilanswer
 

Hello,
 
   Je galere sur un truc qui à l'air con :(
 
   Mon but est de générer du code MIPS pour permettre de multiplier un nombre entier par une
valeur m avec un minimum de décalages, d'addition et de soustractions.
 
Je m'entraine d'abord à produire des strings lisibles pour l'instant ...
 
Exemples :  
i * 6 = i * 4 + i * 2 = i << 2 + i << 1    OK
i * 7 = i * 8 - i = i << 3 - i                  OK  
...
Donc il ne suffit pas de décomposer en base 2 car i * 15 est plus efficacement calculé par i * 16 - i  
   
 

Code :
  1. string itos(int i) // convert int to string
  2. {
  3.  stringstream s;
  4.  s << i;
  5.  return s.str();
  6. }
  7. int get_n( int x ){
  8.     if ( x == 1 )
  9.         return 0;
  10.     else if ( x == 2 )
  11.         return 1;
  12.     else
  13.         return 1 + get_n( x/2 );
  14. }   
  15. // Fonction qui decompose simplement la multiplication de 2 nombres
  16. // A virer !
  17. string decompose ( int m, const string& var, bool plus ) {
  18.      string s = "";   
  19.      if ( plus == true ) { s = s + " + "; plus = false; }   // Pour l'affichage du premier plus                   
  20.      if ( m == 0 ) { s = " 0 "; }
  21.      else if ( m == 1 ) { s = var; }   
  22.      else if ( (m % 2) == 0 ) {    // SI m est multiple de 2
  23.    
  24.           if ( (m & (m-1)) == 0 ){ // SI m est une puissance de 2
  25.                s = s + var + " << " + itos( get_n( m ) );         
  26.           } else {
  27.               s = s + decompose( m-2, var, plus );       
  28.               s = s + " + " + var + " << 1"; // la c'est provisoire
  29.           }
  30.          
  31.      } else { // SINON  ...
  32.          
  33.           if ( (m-1 & (m-2)) == 0 ){ // SI m-1 est une puissance de 2
  34.                s = s + var + " << " + itos( get_n( m - 1 ) );         
  35.                s = s + " + " + var;     
  36.           }/* else {          // SI  m+1 est puisance de 2
  37.                s = s + decompose( m+1, var, plus );
  38.                s = s + " - " + var;
  39.           } */else {
  40.                  // BOURRIN : avec une boucle on incremente et on regarde si ca peut se gerer ...
  41.                  int i = 1;
  42.                  while ( i <= m  && ((m+i)%2) == 0 ){
  43.                         if ( ((m+i) & (m+i-1)) == 0 ) // SI m est une puissance de 2
  44.                             s = s + var + " << " + itos( get_n( m+i ) );       
  45.                         else {
  46.                           s = s + decompose( m+i, var, plus );       
  47.                         }
  48.                         s = s + " - " + decompose( i, var, plus );       
  49.                         i++;
  50.                  }               
  51.           }
  52.            
  53.      }           
  54.      return s;   
  55. }
  56. int main (int argc, const char* argv []) {
  57.   int d = 24; 
  58.   cout << "i * " << d << " = " << decompose( d, "i", false ) << endl;
  59.   return 0;
  60. }


 
J'ai quelques cas de base qui marchent quand même.


i * 10 = i << 3 + i << 1
i * 17 = i << 4 + i
...
ET la ça mird
i * 24 = i << 4 + i << 1 + i << 1 + i << 1 + i << 1        
au lieu d'un simple
i * 24 = i << 4 + i << 3


 
Une idée quelqu'un ?
 
EDIT :
 
La c'est deja un peu mieu mais bon ca beug pour 25

Code :
  1. string decompose ( int m, const string& var, bool plus ) {
  2.     string s = "";   
  3.     if ( plus == true ) { s = s + " + "; plus = false; }   // Pour l'affichage du premier plus                   
  4.     if ( m == 0 )        { s = " 0 "; }
  5.     else if ( m == 1 )   { s = var;   }   
  6.     else if ( m == 2 )   { s = s + var + " << 1"; }
  7.     else if ( (m & (m-1)) == 0 ) { s = s + var + " << " + itos( get_n( m ) ); }
  8.     else {
  9.       // Le masque
  10.       int temp = m;
  11.       int mask = 1;
  12.      
  13.        while ( mask + 1 != temp && mask <= temp ) {
  14.              mask = mask << 1;
  15.        }
  16.        s = s + var + " << " + itos( get_n( mask ) );                       
  17.        if ( mask + 1 == temp )
  18.             s = s + " + " + var ;
  19.        else
  20.             s = s + " - " + decompose( mask-temp, var, plus );
  21.     }
  22.     return s;   
  23. }



Message édité par Chronoklazm le 26-01-2006 à 03:31:34

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
mood
Publicité
Posté le 25-01-2006 à 23:21:06  profilanswer
 

n°1294314
Trap D
Posté le 29-01-2006 à 18:47:57  profilanswer
 

Salut
 
Pour ta décomposition, n'aurais-tu pas intérêt à décomposer en utilisant les puissances de 2 les plus proches à chaque fois ?
style ce genre d'algo :

Code :
  1. entier n : nombre à décomposer
  2. entier pp : puissance de deux la plus proche
  3. entier signe : à l'initalisation, le signe est +, ensuite il change suivant que le nombre à décomposer est plus grand ou plus petit.
  4. [initialisation]
  5. debut
  6.   signe <- 1
  7.   faire
  8.     pp <- plus_proche(n)
  9.     memoriser(signe)
  10.     memoriser(pp)
  11.     si pp > n alors
  12.       n <- pp - n
  13.       signe <- -signe
  14.     sinon
  15.       n <- n - pp
  16.     fin si
  17.   tant que n <> 0
  18. fin
  19. fonction plus_proche(entier n) retour entier
  20. entier p1
  21. entier p2
  22. début
  23.   p1 <- 2
  24.   p2 <- 1
  25.   tant que p1 < n faire
  26.     p2 <- p1
  27.     p1 <- 2 * p1
  28.   fin tant que
  29.   si p1 - n < n - p2 alors
  30.     plus_proche <- p1
  31.   sinon
  32.     plus_proche <- p2
  33.   fin si
  34. fin


Il est évident qu'en C, on doit pouvoir optimiser la fonction plus_proche en lui faisant renvoyer le reste et le signe.
On doit pouvoir aussi trouver le plus proche en testant les bits à 1 contigus à partir des poids les plus forts.
style  
  pour 15 on prend 16  
  car 15 = 8 * 1 + 4 * 1 + 2 * 1 + 1 * 1
  les bits de 8 et 4 sont contigus et ont la valeur 1
 
alors que pour 11 on prend 8  
  car 11 = 8 * 1 + 4 * 0 + 2 * 1 + 1 * 1
  les bits de 8 et 4 sont contigus et n'ont pas la même valeur
 
 
 
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Décomposition minimale

 

Sujets relatifs
[CSS] Largeur minimale sous IE[CSS] - Fixer une largeur de div minimale ?
décomposition en produit de facteur premierDécomposition de lignes lues dans un fichier
[Réglé - CSS / <DIV>] Taille minimale des "tableaux"Taille minimale "Width" d'un <div>
Nomalisation et couverture minimale[HTML, CSS] Calcul de la largeur minimale
[PHP] Décomposition d'un nombre par 3 et 4[VB] Decomposition de chiffre
Plus de sujets relatifs à : Décomposition minimale


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR