Diff for /rpl/src/depassements.c between versions 1.41 and 1.42

version 1.41, 2013/02/27 17:11:40 version 1.42, 2013/03/16 11:31:40
Line 25 Line 25
   
 /*  /*
 ================================================================================  ================================================================================
   Traitement des dépassements sur les additions entières    Traitement des dépassements sur les additions ou soustractions entières
 ================================================================================  ================================================================================
   Entrée :    Entrée :
     - les deux opérandes signées       - les deux opérandes signées 
Line 40 Line 40
 logical1  logical1
 depassement_addition(integer8 *a, integer8 *b, integer8 *resultat)  depassement_addition(integer8 *a, integer8 *b, integer8 *resultat)
 {  {
     int                         decalage;      if ((*a) == 0)
   
     unsigned_integer8           ua;  
     unsigned_integer8           ub;  
     unsigned_integer8           unite;  
     unsigned_integer8           ur;  
   
     decalage = (sizeof(unsigned_integer8) * 8) - 1;  
   
     if ((((*a) <= 0) && ((*b) >= 0)) ||  
             (((*a) >= 0) && ((*b) <= 0)))  
     {      {
         (*resultat) = (*a) + (*b);          (*resultat) = (*b);
         return(d_absence_erreur);          return(d_absence_erreur);
     }      }
       else if ((*b) == 0)
       {
           (*resultat) = (*a);
           return(d_absence_erreur);
       }
       else if ((((*b) > 0) && ((*a) > (INT64_MAX - (*b)))) ||
               (((*b) < 0) && ((*a) < (INT64_MIN - (*b)))))
       {
           (*resultat) = 0;
           return(d_erreur);
       }
     else      else
     {      {
         ua = abs((*a));          (*resultat) = (*a) + (*b);
         ub = abs((*b));          return(d_absence_erreur);
         ur = ua + ub;      }
         unite = 1;  }
   
         if ((ur >= ua) && (ur <= ((unite << decalage) - 1)))  logical1
   depassement_soustraction(integer8 *a, integer8 *b, integer8 *resultat)
   {
       if ((*a) == 0)
       {
           if ((*a) == INT64_MIN)
         {          {
             (*resultat) = (*a) + (*b);              (*resultat) = 0;
             return(d_absence_erreur);              return(d_erreur);
         }          }
         else          else
         {          {
             (*resultat) = 0;              (*resultat) = -(*b);
             return(d_erreur);              return(d_absence_erreur);
         }          }
     }      }
       else if ((*b) == 0)
       {
           (*resultat) = (*a);
           return(d_absence_erreur);
       }
       else if ((((*b) > 0) && ((*a) < (INT64_MIN + (*b)))) ||
               (((*b) < 0) && ((*a) > (INT64_MAX + (*b)))))
       {
           (*resultat) = 0;
           return(d_erreur);
       }
       else
       {
           (*resultat) = (*a) - (*b);
           return(d_absence_erreur);
       }
 }  }
   
   
Line 93  depassement_addition(integer8 *a, intege Line 115  depassement_addition(integer8 *a, intege
 logical1  logical1
 depassement_multiplication(integer8 *a, integer8 *b, integer8 *resultat)  depassement_multiplication(integer8 *a, integer8 *b, integer8 *resultat)
 {  {
     int                         decalage;      if ((*a) == 0)
   
     unsigned_integer8           limite;  
     unsigned_integer8           lsba;  
     unsigned_integer8           lsbb;  
     unsigned_integer8           lsbr;  
     unsigned_integer8           msba;  
     unsigned_integer8           msbb;  
     unsigned_integer8           msbr;  
     unsigned_integer8           produit_croise;  
     unsigned_integer8           ua;  
     unsigned_integer8           ub;  
     unsigned_integer8           unite;  
   
     decalage = sizeof(unsigned_integer4) * 8;  
     unite = 1;  
   
     ua = abs((*a));  
     ub = abs((*b));  
   
     lsba = (ua << decalage) >> decalage;  
     lsbb = (ub << decalage) >> decalage;  
     msba = ua >> decalage;  
     msbb = ub >> decalage;  
   
     if ((msba != 0) && (msbb != 0))  
     {      {
         (*resultat) = 0;          (*resultat) = 0;
         return(d_erreur);          return(d_absence_erreur);
     }      }
     else      else if ((*b) == 0)
     {      {
         produit_croise = (limite = (msba * lsbb)) + (msbb * lsba);          (*resultat) = 0;
           return(d_absence_erreur);
         /*      }
          * Traitement du débordement sur produit_croisé      else if ((*a) > 0)
          */      {
           if ((*b) > 0)
         if (produit_croise < limite)  
         {          {
             msbr = (msba * msbb) + (produit_croise >> decalage) +              if ((*a) > (INT64_MAX / (*b)))
                     (unite << (decalage + 1));              {
                   (*resultat) = 0;
                   return(d_erreur);
               }
         }          }
         else          else
         {          {
             msbr = (msba * msbb) + (produit_croise >> decalage);              if ((*b) < (INT64_MIN / (*a)))
               {
                   (*resultat) = 0;
                   return(d_erreur);
               }
         }          }
       }
         if (msbr != 0)      else // (*a) < 0
       {
           if ((*b) > 0)
         {          {
             (*resultat) = 0;              if ((*a) < (INT64_MIN / (*b)))
             return(d_erreur);              {
                   (*resultat) = 0;
                   return(d_erreur);
               }
         }          }
         else          else
         {          {
             lsbr = (limite = (lsba * lsbb)) + (produit_croise << decalage);              if (((*a) != 0) && ((*b) < (INT64_MAX / (*a))))
   
             if ((lsbr >= limite) && (lsbr <= ((unite << ((2 * decalage) - 1))  
                     - 1)))  
             {  
                 (*resultat) = (*a) * (*b);  
                 return(d_absence_erreur);  
             }  
             else  
             {              {
                 (*resultat) = 0;                  (*resultat) = 0;
                 return(d_erreur);                  return(d_erreur);
             }              }
         }          }
     }      }
   
       (*resultat) = (*a) * (*b);
       return(d_absence_erreur);
 }  }
   
   
Line 198  depassement_puissance(integer8 *a, integ Line 201  depassement_puissance(integer8 *a, integ
         return(d_erreur);          return(d_erreur);
     }      }
   
     if ((r = abs(*a)) <= 1)      if ((-1 <= (*a)) && ((*a) <= 1))
     {      {
           r = abs((*a));
   
         if ((*a) == 0)          if ((*a) == 0)
         {          {
             (*resultat) = 0;              (*resultat) = 0;

Removed from v.1.41  
changed lines
  Added in v.1.42


CVSweb interface <joel.bertrand@systella.fr>