Annotation of rpl/src/depassements.c, revision 1.62

1.1       bertrand    1: /*
                      2: ================================================================================
1.62    ! bertrand    3:   RPL/2 (R) version 4.1.27
1.61      bertrand    4:   Copyright (C) 1989-2017 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
1.42      bertrand   28:   Traitement des dépassements sur les additions ou soustractions entières
1.1       bertrand   29: ================================================================================
                     30:   Entrée :
                     31:    - les deux opérandes signées 
                     32: --------------------------------------------------------------------------------
                     33:   Sortie :
                     34:    - drapeau d'erreur
                     35: --------------------------------------------------------------------------------
                     36:   Effets de bord : néant
                     37: ================================================================================
                     38: */
                     39: 
                     40: logical1
                     41: depassement_addition(integer8 *a, integer8 *b, integer8 *resultat)
                     42: {
1.42      bertrand   43:    if ((*a) == 0)
                     44:    {
                     45:        (*resultat) = (*b);
                     46:        return(d_absence_erreur);
                     47:    }
                     48:    else if ((*b) == 0)
1.1       bertrand   49:    {
1.42      bertrand   50:        (*resultat) = (*a);
1.1       bertrand   51:        return(d_absence_erreur);
                     52:    }
1.42      bertrand   53:    else if ((((*b) > 0) && ((*a) > (INT64_MAX - (*b)))) ||
                     54:            (((*b) < 0) && ((*a) < (INT64_MIN - (*b)))))
                     55:    {
                     56:        (*resultat) = 0;
                     57:        return(d_erreur);
                     58:    }
1.1       bertrand   59:    else
                     60:    {
1.42      bertrand   61:        (*resultat) = (*a) + (*b);
                     62:        return(d_absence_erreur);
                     63:    }
                     64: }
1.1       bertrand   65: 
1.42      bertrand   66: logical1
                     67: depassement_soustraction(integer8 *a, integer8 *b, integer8 *resultat)
                     68: {
                     69:    if ((*a) == 0)
                     70:    {
                     71:        if ((*a) == INT64_MIN)
1.1       bertrand   72:        {
1.42      bertrand   73:            (*resultat) = 0;
                     74:            return(d_erreur);
1.1       bertrand   75:        }
                     76:        else
                     77:        {
1.42      bertrand   78:            (*resultat) = -(*b);
                     79:            return(d_absence_erreur);
1.1       bertrand   80:        }
                     81:    }
1.42      bertrand   82:    else if ((*b) == 0)
                     83:    {
                     84:        (*resultat) = (*a);
                     85:        return(d_absence_erreur);
                     86:    }
                     87:    else if ((((*b) > 0) && ((*a) < (INT64_MIN + (*b)))) ||
                     88:            (((*b) < 0) && ((*a) > (INT64_MAX + (*b)))))
                     89:    {
                     90:        (*resultat) = 0;
                     91:        return(d_erreur);
                     92:    }
                     93:    else
                     94:    {
                     95:        (*resultat) = (*a) - (*b);
                     96:        return(d_absence_erreur);
                     97:    }
1.1       bertrand   98: }
                     99: 
                    100: 
                    101: /*
                    102: ================================================================================
                    103:   Traitement des dépassements sur les multiplications entières
                    104: ================================================================================
                    105:   Entrée :
                    106:    - les deux opérandes signées 
                    107: --------------------------------------------------------------------------------
                    108:   Sortie :
                    109:    - drapeau d'erreur
                    110: --------------------------------------------------------------------------------
                    111:   Effets de bord : néant
                    112: ================================================================================
                    113: */
                    114: 
                    115: logical1
                    116: depassement_multiplication(integer8 *a, integer8 *b, integer8 *resultat)
                    117: {
1.42      bertrand  118:    if ((*a) == 0)
                    119:    {
                    120:        (*resultat) = 0;
                    121:        return(d_absence_erreur);
                    122:    }
                    123:    else if ((*b) == 0)
1.1       bertrand  124:    {
                    125:        (*resultat) = 0;
1.42      bertrand  126:        return(d_absence_erreur);
1.1       bertrand  127:    }
1.42      bertrand  128:    else if ((*a) > 0)
1.1       bertrand  129:    {
1.42      bertrand  130:        if ((*b) > 0)
1.1       bertrand  131:        {
1.42      bertrand  132:            if ((*a) > (INT64_MAX / (*b)))
                    133:            {
                    134:                (*resultat) = 0;
                    135:                return(d_erreur);
                    136:            }
1.1       bertrand  137:        }
                    138:        else
                    139:        {
1.42      bertrand  140:            if ((*b) < (INT64_MIN / (*a)))
                    141:            {
                    142:                (*resultat) = 0;
                    143:                return(d_erreur);
                    144:            }
1.1       bertrand  145:        }
1.42      bertrand  146:    }
                    147:    else // (*a) < 0
                    148:    {
                    149:        if ((*b) > 0)
1.1       bertrand  150:        {
1.42      bertrand  151:            if ((*a) < (INT64_MIN / (*b)))
                    152:            {
                    153:                (*resultat) = 0;
                    154:                return(d_erreur);
                    155:            }
1.1       bertrand  156:        }
                    157:        else
                    158:        {
1.42      bertrand  159:            if (((*a) != 0) && ((*b) < (INT64_MAX / (*a))))
1.1       bertrand  160:            {
                    161:                (*resultat) = 0;
                    162:                return(d_erreur);
                    163:            }
                    164:        }
                    165:    }
1.42      bertrand  166: 
                    167:    (*resultat) = (*a) * (*b);
                    168:    return(d_absence_erreur);
1.1       bertrand  169: }
                    170: 
                    171: 
                    172: /*
                    173: ================================================================================
                    174:   Traitement des dépassements sur les puissances entières a ** b
                    175: ================================================================================
                    176:   Entrée :
                    177:    - a signé, b non signé.
                    178: --------------------------------------------------------------------------------
                    179:   Sortie :
                    180:    - drapeau d'erreur
                    181: --------------------------------------------------------------------------------
                    182:   Effets de bord : néant
                    183: ================================================================================
                    184: */
                    185: 
                    186: logical1
                    187: depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat)
                    188: {
                    189:    integer8                    i;
                    190: 
                    191:    logical1                    depassement;
                    192: 
1.44      bertrand  193:    integer8                    r;
1.1       bertrand  194: 
                    195:    if ((*b) < 0)
                    196:    {
                    197:        (*resultat) = 0;
                    198:        return(d_erreur);
                    199:    }
                    200: 
1.42      bertrand  201:    if ((-1 <= (*a)) && ((*a) <= 1))
1.1       bertrand  202:    {
                    203:        if ((*a) == 0)
                    204:        {
                    205:            (*resultat) = 0;
                    206:        }
                    207:        else
                    208:        {
1.31      bertrand  209:            if ((*a) > 0)
                    210:            {
                    211:                (*resultat) = 1;
                    212:            }
                    213:            else
                    214:            {
                    215:                (*resultat) = (((*b) % 2) == 0) ? 1 : -1;
                    216:            }
1.1       bertrand  217:        }
                    218: 
                    219:        return(d_absence_erreur);
                    220:    }
                    221: 
                    222:    depassement = d_faux;
1.46      bertrand  223:    r = 1;
1.1       bertrand  224: 
                    225:    for(i = 0; i < (*b); i++)
                    226:    {
                    227:        if (depassement_multiplication(&r, a, &r) == d_erreur)
                    228:        {
                    229:            depassement = d_vrai;
                    230:            break;
                    231:        }
                    232:    }
                    233: 
                    234:    if (depassement == d_vrai)
                    235:    {
                    236:        (*resultat) = 0;
                    237:        return(d_erreur);
                    238:    }
                    239:    else
                    240:    {
1.46      bertrand  241:        (*resultat) = r;
1.43      bertrand  242:        return(d_absence_erreur);
1.1       bertrand  243:    }
                    244: }
                    245: 
                    246: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>