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