Comment detecter un depassement de capacite dans une addition

Comment detecter un depassement de capacite dans une addition - C++ - Programmation

Marsh Posté le 23-04-2004 à 01:16:09    

En fait je voudrais juste que dans le cas ou le resultat depasse la valeur max possible une execption soit generee.

Reply

Marsh Posté le 23-04-2004 à 01:16:09   

Reply

Marsh Posté le 23-04-2004 à 01:30:44    

long a,b;
a= a + b;
if(a > sizeof(long))
//lancer l'exception

Reply

Marsh Posté le 23-04-2004 à 02:21:45    

:lol:
 
on me l'a jamais faite celle là...
 
if( a > sizeof(long) )
 
équivaut à
 
if( a > 4 )


Message édité par bjone le 23-04-2004 à 02:22:59
Reply

Marsh Posté le 23-04-2004 à 02:25:50    

la meilleure solution serait, à froid, mais je suis pas sûr fodra que j'essayes:
 
int secured_add(long a, long b)
{
   long value;
 
   asm {
     mov eax,a
     add eax,b
     jno good
   }
 
   throw(...);
good:
   return value;
}

Reply

Marsh Posté le 23-04-2004 à 02:42:08    

yep ça marche (t'as de la chance je t'ai fait un truc qui marche, passke je me suis jamais pris la tête à tester si j'avais des dépassements non désirés, vu qu'en général il sont désirés :D)
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. class Add_Overflow_Exception
  4. {
  5. public:
  6. long a,b;
  7. Add_Overflow_Exception( int ca, int cb) : a(ca), b(cb) {};
  8. };
  9. long secured_add( long a, long b )
  10. {
  11. long value;
  12. _asm {
  13.  mov eax,a
  14.  add eax,b
  15.  mov value,eax
  16.  jno NoOverflow
  17. }
  18.     throw( Add_Overflow_Exception(a,b) );
  19. NoOverflow:
  20. return value;
  21. }
  22. int main()
  23. {
  24. try {
  25.  // a marche
  26.  cout<<secured_add(4,5)<<endl;
  27.  cout<<secured_add(-1,-1)<<endl;
  28.  cout<<secured_add( 0x7fffffff,0)<<endl; // 0x7fffffff: valeur max pour un entier 32bits signé
  29.  cout<<secured_add( 0x80000000,0)<<endl; // 0x80000000: valeur min pour un entier 32bits signé
  30.  // a kaput  
  31.  cout<<secured_add( 0x7fffffff,1)<<endl;
  32.  cout<<secured_add( 0x80000000,-1)<<endl;
  33. }
  34. catch( Add_Overflow_Exception &e )
  35. {
  36.  cout<<"Dépassement lors de l'addition de '"<<e.a<<"' et '"<<e.b<<"'\n";
  37. }
  38. }


 
donnera:
 

Citation :


9
-2
2147483647
-2147483648
Dépassement lors de l'addition de '2147483647' et '1'


Message édité par bjone le 23-04-2004 à 02:43:50
Reply

Marsh Posté le 23-04-2004 à 06:15:04    

merci bcp. je n aurais jamais pensé a utiliser de l assembleur pour resoudre le probleme.

Reply

Marsh Posté le 23-04-2004 à 07:12:31    

eu... suffit pas tout simplement que a>(a+b) ? enfin pour un unsigned au moin


Message édité par skelter le 23-04-2004 à 07:13:18
Reply

Marsh Posté le 23-04-2004 à 07:14:44    

bon ça y est vous avez fini vos conneries de merde là ?
non mais vous avez complètement pété un plomb là
et je parle de vos conneries en matière d'exception ...
 
la seule solution est  
http://www.enseeiht.fr/~boyer/Tools.html

Reply

Marsh Posté le 23-04-2004 à 08:23:26    

à la place de "jno xxxx" tu peux faire "mov ebx, 0 ; seto bl" dans ebx tu auras 1 si dépassement.

Reply

Marsh Posté le 23-04-2004 à 08:24:24    

C'est drole qd même de marier C++ avec asm ;)


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 23-04-2004 à 08:24:24   

Reply

Marsh Posté le 23-04-2004 à 09:31:27    

euh y a une solution en pure C++ ....
ou est l'interet de cette affreuse bidouille ??

Reply

Marsh Posté le 23-04-2004 à 10:17:36    

J'ai jeté un oeil au lien de Taz, le template est implémenté dans un fichier tpp. Comment ça se fait, je croyais que le stemplates devaient être implémentés dans le .h ?
 
Pour "l'algo" utilisé pour l"incrémentation, il est là:
On vaut additionner B à A :

Code :
  1. if ( B >= 0 ) {
  2.     if ( A > max - B ){
  3.       /* dépassement */
  4.     } else
  5.       A += B;
  6.   } else { // incr < 0
  7.     if ( A < min - B ) {
  8.       // <=> value - incr.value < min
  9.       /* dépassement*/
  10.     } else
  11.       A += B;
  12.   }


 
min et max valent std::numeric_limits<numType>::min() et std::numeric_limits<numType>::max()

Reply

Marsh Posté le 23-04-2004 à 10:22:18    

A la fin du hpp y a ca :
 
#include "CheckedNumeric.tpp"
#include "CheckedNumericNumericLimits.tpp"
 
.... ^^

Reply

Marsh Posté le 23-04-2004 à 11:22:08    

"I can see clearly now"...

Reply

Marsh Posté le 23-04-2004 à 12:09:01    

la mienne elle est ptet crade, mais elle passe pas par 30 comparaisons et branchement.... (et en même temps elle mais en évidence une certaine forme de lacune du langage puisque le hardware expose le dépassement, alors qu'avec le langage on doit faire un hack dégueulasse pour émuler les capacitées du hardware)
 
concernant l'exception, c'est un exemple Tazeuuuuuuuuu.....

Reply

Marsh Posté le 23-04-2004 à 12:55:02    

bjone a écrit :

la mienne elle est ptet crade, mais elle passe pas par 30 comparaisons et branchement.... (et en même temps elle mais en évidence une certaine forme de lacune du langage puisque le hardware expose le dépassement, alors qu'avec le langage on doit faire un hack dégueulasse pour émuler les capacitées du hardware)
 
concernant l'exception, c'est un exemple Tazeuuuuuuuuu.....

le hack dégeux, c'est justement ton assembleur non-portable et en pkus difficile à utiliser dans du code alors qu'avec mon lien, tu peux invertir code normal avec des types de entiers et CN<type entiers> sans problème

Reply

Marsh Posté le 23-04-2004 à 13:25:51    

j'ai précisé "pour émuler les capacitées du hardware". (c'est vrai que c'est assez variable)
 
mais si dans le C++ on déinierai un truc comme ça:
 
try (check_for_overflow)
{
  a=(b+c)/d;
}
 
catch( add_overflow e)
{
   ...
}
 
catch( div_overflow e )
{
 ...
}
 
je n'ai pas de solution miracle, mais il est vrai qu'une solution asm est un hack dégueu non portable, mais qu'une solution par bricolage de langage alors que la hardware offre potentiellement la chose est aussi un hack dégueu d'un autre point de vue.
 
ce qui serait bien c'est qu'au niveau ISO/ANSI/IEEE, une extension soit proposé pour le C++, afin d'utiliser les capacitées hardware, voir de les améliorer (il y a bien une exception pour les divisions par zéro, on peut très bien ajouter une exception à l'archi x86 quand le bit d'overflow est déclenché dans le registre des flags)
 
enfin ce que j'en dit.... (je fais juste que proposer hein)

Reply

Marsh Posté le 23-04-2004 à 17:10:52    

Citation :

on peut très bien ajouter une exception à l'archi x86 quand le bit d'overflow est déclenché dans le registre des flags


Si on est ingénieur chez Intel peut être, sinon...

Reply

Marsh Posté le 23-04-2004 à 19:52:39    

Le code officiel de dépassement :
OverFlow = Carry0(MSB)^Carry0(MSB-1)
 
source : intel

Reply

Marsh Posté le 23-04-2004 à 20:53:15    

Questions bêtes au hasard...  
a) si a est signé il suffirait de comparer le signe de a avant et après l'opération, non (attention au cas du passage par zéro) ? Ou s'il est non signé, vérifier que le résultat est supérieur (ou égal) à la valeur d'origine (pour une addition).
b) pour quelle utilisation particulière a-t'on besoin de faire une telle vérification ?


Message édité par el muchacho le 23-04-2004 à 21:09:04
Reply

Marsh Posté le 26-04-2004 à 09:33:17    

Dans les 2 cas il suffit de vérifier que a1 > a0 après opération.

Reply

Marsh Posté le 26-04-2004 à 20:37:55    

Pas si tu sommes deux entiers négatifs. On est obligé de distinguer le cas où b est < 0, d'où le code un peu tordu que tu as donné plus haut.


Message édité par el muchacho le 26-04-2004 à 20:39:35
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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