Diff for /rpl/src/depassements.c between versions 1.3 and 1.49

version 1.3, 2010/02/10 10:14:19 version 1.49, 2013/12/03 09:36:10
Line 1 Line 1
 /*  /*
 ================================================================================  ================================================================================
   RPL/2 (R) version 4.0.11    RPL/2 (R) version 4.1.17
   Copyright (C) 1989-2010 Dr. BERTRAND Joël    Copyright (C) 1989-2013 Dr. BERTRAND Joël
   
   This file is part of RPL/2.    This file is part of RPL/2.
   
Line 20 Line 20
 */  */
   
   
 #include "rpl.conv.h"  #include "rpl-conv.h"
   
   
 /*  /*
 ================================================================================  ================================================================================
   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 183  depassement_multiplication(integer8 *a, Line 186  depassement_multiplication(integer8 *a,
 logical1  logical1
 depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat)  depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat)
 {  {
     int                         decalage;  
   
     integer8                    i;      integer8                    i;
   
     logical1                    depassement;      logical1                    depassement;
   
     unsigned_integer8           r;      integer8                    r;
     unsigned_integer8           unite;  
   
     if ((*b) < 0)      if ((*b) < 0)
     {      {
Line 198  depassement_puissance(integer8 *a, integ Line 198  depassement_puissance(integer8 *a, integ
         return(d_erreur);          return(d_erreur);
     }      }
   
     if ((*a) <= 1)      if ((-1 <= (*a)) && ((*a) <= 1))
     {      {
         if ((*a) == 0)          if ((*a) == 0)
         {          {
Line 206  depassement_puissance(integer8 *a, integ Line 206  depassement_puissance(integer8 *a, integ
         }          }
         else          else
         {          {
             (*resultat) = 1;              if ((*a) > 0)
               {
                   (*resultat) = 1;
               }
               else
               {
                   (*resultat) = (((*b) % 2) == 0) ? 1 : -1;
               }
         }          }
   
         return(d_absence_erreur);          return(d_absence_erreur);
     }      }
   
     depassement = d_faux;      depassement = d_faux;
     r = abs(*a);      r = 1;
   
     for(i = 0; i < (*b); i++)      for(i = 0; i < (*b); i++)
     {      {
Line 231  depassement_puissance(integer8 *a, integ Line 238  depassement_puissance(integer8 *a, integ
     }      }
     else      else
     {      {
         decalage = (sizeof(unsigned_integer8) * 8) - 1;          (*resultat) = r;
         unite = 1;          return(d_absence_erreur);
   
         if (r <= ((unite << decalage) - 1))  
         {  
             f77puissanceii_(a, b, resultat);  
             return(d_absence_erreur);  
         }  
         else  
         {  
             (*resultat) = 0;  
             return(d_erreur);  
         }  
     }      }
 }  }
   

Removed from v.1.3  
changed lines
  Added in v.1.49


CVSweb interface <joel.bertrand@systella.fr>