Il y a (1):
// assume x,y are non-negative
if(x > max - y) error;
Et (2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
Lequel est préféré ou existe-t-il une meilleure façon.
Le débordement d'entier est l'exemple canonique de "comportement indéfini" en C (en notant que les opérations sur des entiers non signés ne débordent jamais, elles sont définies pour boucler à la place). Cela signifie qu'une fois que vous avez exécuté x + y
, s'il a débordé, vous êtes déjà arrosé. Il est trop tard pour faire une vérification - votre programme pourrait déjà avoir planté. Pensez-y comme vérifier la division par zéro - si vous attendez que la division soit exécutée pour vérifier, il est déjà trop tard.
Cela implique donc que la méthode (1) est la seule façon correcte de le faire. Pour max
, vous pouvez utiliser INT_MAX
de <limits.h>
.
Si x
et/ou y
peut être négatif, alors les choses sont plus difficiles - vous devez faire le test de telle manière que le test lui-même ne puisse pas provoquer de débordement.
if ((y > 0 && x > INT_MAX - y) ||
(y < 0 && x < INT_MIN - y))
{
/* Oh no, overflow */
}
else
{
sum = x + y;
}
Vous ne pouvez vraiment vérifier le débordement qu'avec unsigned
entiers et arithmatiques:
unsigned a,b,c;
a = b + c;
if (a < b) {
/* overflow */
}
Le comportement du débordement avec des entiers signés n'est pas défini en C, mais sur la plupart des machines, vous pouvez utiliser
int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
/* overflow */
}
Cela ne fonctionnera pas sur les machines qui utilisent tout type d'arithmétique saturante