Comment détecter un débordement sur les multiplications d'entiers en C

Comment détecter un débordement sur les multiplications d'entiers en C - C - Programmation

Marsh Posté le 10-10-2007 à 21:15:32    

Bonjour à tous!
 
J'aurais besoin de faire une validation dans un programme mais je n'arrive pas a voir comment la faire.
Je doit pouvoir vérifier s'il ya eu débordement à la suite d'une multiplication sur des entiers non signés en C.
 
Dison que j'ai des variables du genre:
 
unsigned int a = ...; //où ... veut dire peu importe l'entier valide
unsigned int b = ...;
 
unsigned int c = a * b;
 
Je doit donc faire une validation sur c pour voir s'il y a eu débordement/overflow mais je ne vois pas comment faire.
 
Merci d'avance pour votre aide.

Reply

Marsh Posté le 10-10-2007 à 21:15:32   

Reply

Marsh Posté le 10-10-2007 à 21:28:03    

Bah avec un test à la con du genre :
 
#include <limits.h>
 
if (UINT_MAX / b > a) puts("haha, bien tenté" )


Message édité par tpierron le 10-10-2007 à 21:28:48
Reply

Marsh Posté le 10-10-2007 à 21:35:45    

Je vois, merci c'est bien mais ya pas moyen de faire ce truc sans include <limits.h> et seulement avec des opératiers arithmétiques.. un truc logique que j'aurais pas pigé du genre pour une addition tu verrifierais si les deux variables a et b sont de même signe et si la variable b est du signe contraire il y a eu débordement. Merci parcontre.
 
edit: Oh et dans l'exemple d'addition que j'ai mentionné sa s'applique aux entiers signés mais bon, ce genre de validation.


Message édité par eliane1 le 10-10-2007 à 21:42:50
Reply

Marsh Posté le 10-10-2007 à 22:12:29    

Pour la multiplication, il ne suffit pas de vérifier les signes de a et b.
En fait il n'y a pas d'algo simple pour ça.
 
Par contre tu peux faire le calcul avec un c qui serait un unsigned long long (si sur ta machine un long long est au moins deux fois plus grand qu'un int) et de vérifier si c appartient à [INT_MIN; INT_MAX]
 
genre :
 
unsigned int a,b,c;
unsigned long long tmp = unsigned long long)a * (unsigned long long)b;
 
if ( (tmp > INT_MAX) || (tmp < INT_MIN) ) {
  /* Débordement */
}
c = (unsigned int)tmp;
 

Reply

Marsh Posté le 10-10-2007 à 22:51:12    

LOL je viens d'y penser et je croit qu'un simple if(c/b) != a fonctionnerais. Dite moi le si c'est faux mais sa me semble logique.

Reply

Marsh Posté le 10-10-2007 à 23:20:00    

Mouais, ça me semble tout aussi bien, sinon mieux. À vérifier que b != 0, comme je ne l'ai pas fait dans mon exemple.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed