Produit d'int quand depassement du 2^32.

Résolu
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008 - 26 nov. 2005 à 00:53
bipcpp Messages postés 40 Date d'inscription mardi 18 mai 2004 Statut Membre Dernière intervention 2 mai 2010 - 26 nov. 2005 à 20:26
Bonjour a tous,

Mon code, a un moment donne, fait le produit de deux int, j'aimerais faire une gestion d'erreur (soit un simple exit(0)) lorque le resultat de ce produit, que je dois mettre dans un autre int, depasse 2^32.

Le probleme que j'ai est que je ne peux stocker ce produit nulle part pour le comparer a la taille d'un int, puisque aucuns type ne peut le contenir (2milliard x 2milliard par exemple).

J'avais pense au passage d'int en chaine puis de produit de deux chaine, mais mon programme est court a la base, je ne vais pas rajouter une page juste pour gere une erreur!
Mais si quelqu'un a une autre solution...
Merci d'avance (:

22 réponses

vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 01:09
Si c'est pour les cours, je pense que l'assembleur n'est pas la solution attendue
Si tu as juste a détécter l'erreur, tu peux le faire simplement:
Tu veux vérifier que a*b<2^32, tu vérifies donc que a<2^32/b
3
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 00:55
Tu as le type __in64
Sinon, tu peux coder en assembleur, le résultat est sur 64 bits (2 reg de 32 bits)
0
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008
26 nov. 2005 à 01:01
Merci de ta reponse (rapide).

Je n'ai pas precise mais je ne peux faire ca qu'en C (etudiant..), et sans rajouter de lib specifique a moins de recoder ce qu'il faut..

Je me trompe peutetre mais ce type a l'air d'etre utilise seulement en C++?
Assembleur? Je ne connais pas du tout mais a priori on a le droit vu que le C le prend en charge, je crois, mais je n'y connais rien ...
0
cs_Joky Messages postés 1787 Date d'inscription lundi 22 novembre 2004 Statut Membre Dernière intervention 31 janvier 2009 2
26 nov. 2005 à 01:10
Un DWORD c'est 32 bits non ?

32 bits -> 11111111111111111111111111111111

En décimal : 4 294 967 295

Je sais pas si ça te convient...


if(!Meilleur("Joky")) return ERREUR;
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 01:13
Belle intervention Joky, mais je crois que t'a pas bien compris le problème.
Si tu fais une multiplication qui déborde, ca va donner un résultat, sans doute inférieur à 0xFFFFFFFF
0
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008
26 nov. 2005 à 01:30
C'est logique vecchio56, je vais essayer ca!
Merci beaucoup pour ton aide.
0
cs_Joky Messages postés 1787 Date d'inscription lundi 22 novembre 2004 Statut Membre Dernière intervention 31 janvier 2009 2
26 nov. 2005 à 01:33
Okay donc je réitère :)

Soit n un entier à p chiffres :)

Construisons alors un tableau de int qui contiendrons les entiers de rang p

En sachant que le nombre de chiffre dépendra de la longueur de la chaines :)

Faisons cela pour les 2 entier à multiplier !

Stockons les nouvelles valeurs dans un tableau

Trouver sa dimention

Si la dimension est trop grande, par exemple elle contient 12 chiffres, et bien erreur sinon pas erreur :)


if(!Meilleur("Joky")) return ERREUR;<
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 01:36
Il faudra donc que tu recodes la multiplication?
Et je vois pas le lien avec ton premier message :)
0
kaervas Messages postés 51 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 19 avril 2008
26 nov. 2005 à 01:37
Interessant Joky, ca semble plus generique comme methode,
la premiere plus adapte pour mon cas (rapidite), mais je prends note de celle-ci, merci (:
0
cs_Joky Messages postés 1787 Date d'inscription lundi 22 novembre 2004 Statut Membre Dernière intervention 31 janvier 2009 2
26 nov. 2005 à 01:38
Exmple pour 24 * 15



TabInt[0][0] = 4;

TabInt[0][1] = 2;

TabInt[1][0] = 5;

TabInt[1][1] = 1;



Ensuite :

Produit[0] = 4 * 5 = 20 -> On garde 0 on retient 2

Produit[1] = 5 * 2 + 1 * 4 + 2 -> 10 + 4 + 2 -> 0(On retient le 1) + 4 +2 -> 6

Produit[2] = 1 * 2 + 1 = 3



Résultat 3 6 0

Enfin bref après faut trouver la dimention voir si elle est supérieure à celle autorisée :)

J'trouve ça un peu long comme méthode lol :)

if(!Meilleur("Joky")) return ERREUR;<
0
cs_Joky Messages postés 1787 Date d'inscription lundi 22 novembre 2004 Statut Membre Dernière intervention 31 janvier 2009 2
26 nov. 2005 à 01:40
C'est claire c'est fastidieux lol

Autant ne pas faire la gestion de l'erreur enfin c'est ce que je ferais lol

if(!Meilleur("Joky")) return ERREUR;<
0
cs_Joky Messages postés 1787 Date d'inscription lundi 22 novembre 2004 Statut Membre Dernière intervention 31 janvier 2009 2
26 nov. 2005 à 03:23
Découpage des chiffres :p



// Si 1 -> Retourne 10

// Si 2 -> Retourne 100

// etc...

long GetDivide(int NbrOfZero)

{

long lToReturn = 0;

if(NbrOfZero == 0)

return 1;

else

return 10*GetDivide(NbrOfZero-1);

}



int* CutNumber(int Nb)

{

char Buff[MAX_PATH];

const char *c = itoa(Nb, Buff, 10);



int iSize = strlen(c)-1;



int *iTab = (int*)malloc(iSize+1);



for(int i=0; i<=iSize; i++)

{

iTab[i] = (int)(Nb/GetDivide(iSize-i));

Nb -= iTab[i]*GetDivide(iSize-i);

}



return iTab;

}



Par contre, je ne te garantie pas que c'est bon lol, il peut y avoir quelques souci je pense :(

if(!Meilleur("Joky")) return ERREUR;<
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 09:18
Oui, là tu t'es pris la tete pour rien. Plus simplement tu utilises des divisions par 10 et des modulo 10
Excuse moi de te dire ca mais ta solution est horrible ;)
0
cs_Tidam Messages postés 124 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 février 2006 2
26 nov. 2005 à 11:17
Perso je ne vois pas pourquoi vous vous cassez la tete ... la
multiplication de deux chiffres de longueur len1 et len2 tient toujours
sur la longueur len1 + len2, donc pour moi il suffirait de chopper la
longueur des deux entiers, comparer la longueur maximale qu'on peut
atteindre avec un unsigned int, si ca tient dans un unsigned, on fait
le calcul en unsigned, que l'on compare a 2^31 et si c'est bon on le
met dans un int ...

Je ne vois pas pourquoi vous voulez faire des tableaux etc...
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 11:22
Parce que certains nombres de 'longueur' 10 sont inférieurs à 2^32 et d'autres sont supérieurs, donc l'argument longueur ne suffit pas.
De toute facons, je crois kaervas a déja opté pour la méthode que j'ai donnée plus haut qui est plus simple pour seulement détecter l'erreur
0
cs_Tidam Messages postés 124 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 février 2006 2
26 nov. 2005 à 12:24
mais C pour ca que je disais de comparer la longueur maximale a la
longueur d'un unsigned int, car comme ca on est certain d'avoir au moin
tous les cas possible pour le signed int
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 13:28
Tu pourrais être plus précis? Je vois pas trop comment tu ferais, sans calculer le résultat:

par exemple 56789*56789 est supérieur 2^32
Mais 12345*12345 est inférieur à 2^32

Ce qu'on veut savoir c'est: est-ce que le résultat de la multiplication est valide. Si tu ne te bases que sur les longueurs, tu aura la même réponse pour les deux exemples précédents, or un des deux seulement provoque une erreur
0
bipcpp Messages postés 40 Date d'inscription mardi 18 mai 2004 Statut Membre Dernière intervention 2 mai 2010
26 nov. 2005 à 17:33
Le plus court est peut-être de faire une division :



if (int1 > (MAX_INT / int2))

// dépassement

else

result = int1 * int2;
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
26 nov. 2005 à 17:37
oui c'est mon deuxième message :)
0
cs_Tidam Messages postés 124 Date d'inscription jeudi 2 janvier 2003 Statut Membre Dernière intervention 16 février 2006 2
26 nov. 2005 à 17:44
Alors ca c'est pas bete une division ... reste a voir si ca marche tout le temps ...
0
Rejoignez-nous