Ajout et soustraction de Bigints à l’aide de listes chaînées

J’ai presque fini cette mission et ça me tue. Ceci est mon troisième article sur trois sections différentes et honnêtement, je suis gêné de devoir lutter autant avec la tâche.

L’affectation elle-même consiste à créer un programme qui effectue l’addition et la soustraction de grands nombres entiers à l’aide de listes chaînées (et je commence lentement à détester les listes chaînées, en dehors de Lisp). Tout semble fonctionner maintenant, sauf pour l’addition et la soustraction. Je ne sais pas si ce sont les fonctions arithmétiques, car elles fonctionnaient auparavant (mais jamais à 100%), mais cela ne fait pas de mal de vérifier auprès de la communauté S / O (normalement, je ne demanderais pas autant aider à une mission parce que je préfère résoudre mon problème moi-même, mais la semaine a été affreuse et mouvementée, et la date limite approche à grands pas).

Les fonctions arithmétiques que j’ai écrites sont les suivantes. Quelqu’un peut-il m’aider à identifier ce qui ne va pas?

/* * Function add * * @Paramater STRUCT* Integer * @Parameter STRUCT* Integer * * Takes two linked lists representing * big integers stored in reversed order, * and returns a linked list containing * the sum of the two integers. * * @Return STRUCT* Integer * * TODO Comment me */ struct integer* add( struct integer *p, struct integer *q ) { int carry = 0; struct integer *sHead, *sCurr; struct integer *pHead, *qHead; pHead = p; qHead = q; sHead = NULL; while( p ) { sCurr = ( struct integer* ) malloc (sizeof(struct integer)); sCurr->digit = p->digit + q->digit + carry; sCurr->next = sHead; sHead = sCurr; carry = 0; /* * If the current digits sum to greater than 9, * create a carry value and replace the current * value with value mod 10. */ if( sCurr->digit > 9 ) { carry = 1; sCurr->digit = sCurr->digit % 10; } /* * If the most significant digits of the numbers * sum to 10 or greater, create an extra node * at the end of the sum list and assign it the * value of 1. */ if( carry == 1 && sCurr->next == NULL ) { struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer)); sCarry->digit = 1; sCarry->next = NULL; reverse( &sCurr ); sCurr->next = sCarry; reverse( &sCurr ); } p = p->next; if( q->next ) q = q->next; else q->digit = 0; } return sHead; } 

 /* * Function subtract * * @Parameter STRUCT* Integer * @Parameter STRUCT* Integer * * Takes two linked lists representing struct integers. * Traverses through the lists, subtracting each * digits from the subsequent nodes to form a new * struct integer, and then returns the newly formed * linked list. * * @Return STRUCT* Integer * * TODO Comment me */ struct integer* subtract( struct integer *p, struct integer *q ) { int borrow = 0; struct integer *dHead, *dCurr; struct integer *pHead, *qHead; pHead = p; qHead = q; dHead = NULL; while( p ) { dCurr = (struct integer*) malloc (sizeof(struct integer)); if( q ) { dCurr->digit = p->digit - q->digit - borrow; } else { dCurr->digit = p->digit - borrow; } dCurr->next = dHead; if( dCurr->digit digit += 10; borrow = 1; } dHead = dCurr; p = p->next; if( q->next) q = q->next; } return dHead; } 


L’exemple de sortie devrait ressembler à ceci:

 8888888888 + 2222222222 = 11111111110 10000000000 – 9999999999 = 1 10000000000 – 9999999999 = 1 

mais à la place, cela ressemble à ceci:

 8888888888 + 2222222222 = 1111111110 10000000000 - 9999999999 = 10000000001 10000000000 - 9999999999 = 10000000001 

EDIT L’ensemble du programme, dans sa forme actuelle à partir de 15h30 HNE, est disponible ici pour référence ou si ces fonctions ne sont pas en cause.

else q->digit = 0;
Vous changez l’argument dans la fonction.

Essayez de changer vos fonctions pour accepter les arguments const et recomstackr.

 struct integer* add( const struct integer *p, const struct integer *q ) struct integer* subtract( const struct integer *p, const struct integer *q ) 

La partie qui lit

 if( dCurr->next == NULL && carry == 1 ) { struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer)); dCarry->digit = -1; dCarry->next = NULL; dCurr->next = dCarry; } 

semble un peu hors de propos. Dans le code ci-dessus, dCurr->next est défini pour être les chiffres que nous avons déjà calculés dans les boucles précédentes, il est donc uniquement NULL pour le premier chiffre. Je pense que vous vouliez vérifier p->next place.

Je suppose que la condition len(p) >= len(q) est valable pour cette fonction. Sinon, vous devrez faire quelque chose pour gérer ce qui ne l’est pas (manquer de p noeuds avant de manquer de q noeuds). Je suppose également que les chiffres figurent dans la liste, du chiffre le moins significatif au plus significatif. Sinon, vous devrez peut-être inverser p et q avant de les traiter.

Une autre chose que je ne comprends pas, c’est comment vous gérez les nombres négatifs. Ou même si vous êtes censé les gérer. Il n’est pas facile d’append à une structure comme celle-ci, car une approche naïve consistant à append quelque chose à la fin ne fonctionnerait pas lors de la soustraction: lorsque q est négatif, vous aurez tout le mal à soustraire q à p, puis vous découvrirez que vous auriez dû append à la place.

Dans la fonction compare() vous “marchez” p et essayez ensuite de marcher à nouveau.

 int compare( struct integer *p, struct integer *q ) { /* ... */ while( p ) { pCount++; p = p->next; } 

p est maintenant NULL

  /* ... */ while( p ) { /* ... */ } 

La boucle while ne court jamais.