--- rpl/src/depassements.c 2010/08/06 15:26:44 1.11 +++ rpl/src/depassements.c 2022/09/07 13:40:30 1.71 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.18 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.34 + Copyright (C) 1989-2021 Dr. BERTRAND Joël This file is part of RPL/2. @@ -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); } @@ -183,14 +186,11 @@ depassement_multiplication(integer8 *a, logical1 depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat) { - int decalage; - integer8 i; logical1 depassement; - unsigned_integer8 r; - unsigned_integer8 unite; + integer8 r; if ((*b) < 0) { @@ -198,7 +198,7 @@ depassement_puissance(integer8 *a, integ return(d_erreur); } - if ((*a) <= 1) + if ((-1 <= (*a)) && ((*a) <= 1)) { if ((*a) == 0) { @@ -206,14 +206,21 @@ depassement_puissance(integer8 *a, integ } else { - (*resultat) = 1; + if ((*a) > 0) + { + (*resultat) = 1; + } + else + { + (*resultat) = (((*b) % 2) == 0) ? 1 : -1; + } } return(d_absence_erreur); } depassement = d_faux; - r = abs(*a); + r = 1; for(i = 0; i < (*b); i++) { @@ -231,19 +238,8 @@ depassement_puissance(integer8 *a, integ } else { - decalage = (sizeof(unsigned_integer8) * 8) - 1; - unite = 1; - - if (r <= ((unite << decalage) - 1)) - { - f77puissanceii_(a, b, resultat); - return(d_absence_erreur); - } - else - { - (*resultat) = 0; - return(d_erreur); - } + (*resultat) = r; + return(d_absence_erreur); } }