/* ================================================================================ RPL/2 (R) version 4.1.27 Copyright (C) 1989-2017 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Traitement des dépassements sur les additions ou soustractions entières ================================================================================ Entrée : - les deux opérandes signées -------------------------------------------------------------------------------- Sortie : - drapeau d'erreur -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 depassement_addition(integer8 *a, integer8 *b, integer8 *resultat) { if ((*a) == 0) { (*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 { (*resultat) = (*a) + (*b); return(d_absence_erreur); } } logical1 depassement_soustraction(integer8 *a, integer8 *b, integer8 *resultat) { if ((*a) == 0) { if ((*a) == INT64_MIN) { (*resultat) = 0; return(d_erreur); } else { (*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); } } /* ================================================================================ Traitement des dépassements sur les multiplications entières ================================================================================ Entrée : - les deux opérandes signées -------------------------------------------------------------------------------- Sortie : - drapeau d'erreur -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 depassement_multiplication(integer8 *a, integer8 *b, integer8 *resultat) { if ((*a) == 0) { (*resultat) = 0; return(d_absence_erreur); } else if ((*b) == 0) { (*resultat) = 0; return(d_absence_erreur); } else if ((*a) > 0) { if ((*b) > 0) { if ((*a) > (INT64_MAX / (*b))) { (*resultat) = 0; return(d_erreur); } } else { if ((*b) < (INT64_MIN / (*a))) { (*resultat) = 0; return(d_erreur); } } } else // (*a) < 0 { if ((*b) > 0) { if ((*a) < (INT64_MIN / (*b))) { (*resultat) = 0; return(d_erreur); } } else { if (((*a) != 0) && ((*b) < (INT64_MAX / (*a)))) { (*resultat) = 0; return(d_erreur); } } } (*resultat) = (*a) * (*b); return(d_absence_erreur); } /* ================================================================================ Traitement des dépassements sur les puissances entières a ** b ================================================================================ Entrée : - a signé, b non signé. -------------------------------------------------------------------------------- Sortie : - drapeau d'erreur -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat) { integer8 i; logical1 depassement; integer8 r; if ((*b) < 0) { (*resultat) = 0; return(d_erreur); } if ((-1 <= (*a)) && ((*a) <= 1)) { if ((*a) == 0) { (*resultat) = 0; } else { if ((*a) > 0) { (*resultat) = 1; } else { (*resultat) = (((*b) % 2) == 0) ? 1 : -1; } } return(d_absence_erreur); } depassement = d_faux; r = 1; for(i = 0; i < (*b); i++) { if (depassement_multiplication(&r, a, &r) == d_erreur) { depassement = d_vrai; break; } } if (depassement == d_vrai) { (*resultat) = 0; return(d_erreur); } else { (*resultat) = r; return(d_absence_erreur); } } // vim: ts=4