Problem: Ziffernweise Division
-
Bei mir hängst ärger bei der Ziffernweise Division.
Die Funktion zur Division lautet void div(const int *z1, const int *z2, int *erg, int *rest, int lang), zur schnelleren Orientierung. Ich komm einfach nicht dahinter wo das Problem steckt... Die Subtraktion stimmt, setzFeldNull passt auch, ausgabe stimmt auch... div sollte eigentlich auch stimmen... Kanns sein das er vllt. einen Fehler bekommt weil ich ihm 2x die selbe Adresse in sub übergebe, 1x const und 1x normal?
mfG Terrasearch#include <stdio.h> #include <math.h> #include <string.h> #include <ctype.h> #define LAENGE 60 int isIntFeld(const char *ein); void setzFeldNull(int *feld, int lang); int speichereWert(const char *ch, int *zahl, int lang); void ausgabe(const int *zahl, int lang); void add(const int *z1, const int *z2, int *erg, int lang); void sub(const int *z1, const int *z2, int *erg, int lang); void mul(const int *z1, const int *z2, int *erg, int lang); void div(const int *z1, const int *z2, int *erg, int *rest, int lang); int a_gleich_b(const int *z1, const int *z2, int lang); void hilfe(); int Menu(char *ch,int *zahl1,int *zahl2,int *ergebnis,int *rest,int lang); int main(){ int zahl1[LAENGE], zahl2[LAENGE], ergebnis[LAENGE*2], rest[LAENGE]; char ch[LAENGE+1]=""; hilfe(); Menu(ch,zahl1,zahl2,ergebnis,rest,LAENGE); printf("Druecken sie eine beliebige Taste um das Programm zu beenden..."); getch(); return 0; }//main int isIntFeld(const char *ein){ int i; for(i=0;ein[i]!='\0';i++) if(!isdigit(ein[i])) return 0; return 1; }//isZahl ende void setzFeldNull(int *feld, int lang){ int i; for(i=0;i<lang;i++) feld[i]=0; }//setzAufNull ende int speichereWert(const char *ch, int *zahl, int lang){ int i; for(i=0;ch[i]!='\0';i++) zahl[lang-strlen(ch)+i]=ch[i]-'0'; }//speichereWert ende void ausgabe(const int *zahl, int lang){ int i,j; for(i=0;zahl[i]=='\0'&&i<lang;i++) ; for(j=0;i<lang;i++,j++) printf("%d",zahl[i]); if(j==0) putchar('0'); }//ausgabe ende void add(const int *z1, const int *z2, int *erg, int lang){ int i; for(i=lang-1;i>=0;i--){ erg[i]+=z1[i]+z2[i]; if(erg[i]>9){ erg[i-1]+=1; erg[i]-=10; } } }//add ende void sub(const int *z1, const int *z2, int *erg, int lang){ int i, h=a_gleich_b(z1,z2,lang); if(h>0){ for(i=lang-1;i>=0;i--){ erg[i]+=z1[i]-z2[i]; if(erg[i]<0){ erg[i-1]-=1; erg[i]+=10; } } } if(h<0){ for(i=lang-1;i>=0;i--){ erg[i]+=z2[i]-z1[i]; if(erg[i]<0){ erg[i-1]-=1; erg[i]+=10; } } for(i=0;erg[i]=='\0'&&i<lang;i++) ; erg[i]*=-1; } }//sub ende void mul(const int *z1, const int *z2, int *erg, int lang){ int i,j,k,l,hilf; for(i=0;z1[i]=='\0'&&i<lang;i++) ; for(j=0;z2[j]=='\0'&&i<lang;j++) ; for(k=i;k<lang;k++) for(l=j;l<lang;l++) erg[k+l+1]+=z1[k]*z2[l]; for(i=lang*2;i>0;i--){ hilf=erg[i]/10; erg[i-1]+=hilf; erg[i]-=hilf*10; } }//mul ende void div(const int *z1, const int *z2, int *erg, int*rest, int lang){ int i,j; for(i=0;i<lang;i++){ rest[lang-1]=z1[i]; while(a_gleich_b(rest,z2,lang)>0){ sub(rest,z2,rest,lang); erg[i]++; } for(j=1;j<lang;j++) rest[j-1]=rest[j]; } }//div ende int a_gleich_b(const int *z1, const int *z2, int lang){ int i, hilf=0; for(i=0;i<lang&&hilf==0;i++){ hilf=z1[i]-z2[i]; } return hilf; }//a_glecih_b ende void hilfe(){ system("cls"); printf("%40s","Hilfe\n\n\n"); printf("Dies ist ein 60-stelliger Taschenrechner.\n"); printf("Im Menue koennen Sie zwischen 4 verschiedenen Rechenoperationen "); printf("waehlen.\n"); printf("Haben Sie sich fuer einen Operator korrekt entschieden, "); printf("koennen Sie zwei \npositive bis zu 60-stellige Zahlen eingeben.\n"); printf("Zum Schluss werden Sie aufgefordert sich zu entscheiden ob Sie"); printf(" nochmals mit dem\nselben Rechenoperator arbeiten wollen, "); printf("in das Menue wechseln wollen,\noder das Programm beenden wollen.\n"); printf("\nDruecken Sie eine beliebige Taste um in das Menue zu wechseln."); getch(); system("cls"); } int Menu(char *ch,int *zahl1,int *zahl2,int *ergebnis,int *rest,int lang){ int i; char c,c2; do{ printf("Welche Rechnung moechten Sie durchfuehren?\n"); printf("(1)Addition\n"); printf("(2)Subtraktion\n"); printf("(3)Multiplikation\n"); printf("(4)Division - noch in Bearbeitung\n"); printf("(5)Hilfe\n"); printf("(0)Ende\n"); printf("< >\b\b"); i=0; do{ if(i) printf("\b\b< > Falsche Eingabe\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); c=getche(); i=1; }while(c<'0'||c>'5'); system("cls"); if(c!='5'&&c!='0'){ do{ setzFeldNull(zahl1,LAENGE); setzFeldNull(zahl2,LAENGE); setzFeldNull(ergebnis,LAENGE*2); setzFeldNull(rest,LAENGE); switch(c){ case '1':printf("%35s\n","Addition"); break; case '2':printf("%35s\n","Subtraktion"); break; case '3':printf("%35s\n","Multiplikation"); break; case '4':printf("%35s\n","Division"); break; } do{ printf("\nGeben Sie die erste Zahl ein\n"); gets(ch); }while(!isIntFeld(ch)); speichereWert(ch,zahl1,lang); do{ printf("\nGeben Sie die zweite Zahl ein\n"); gets(ch); }while(!isIntFeld(ch)); speichereWert(ch,zahl2,lang); switch(c){ case '1':add(zahl1,zahl2,ergebnis,lang); break; case '2':sub(zahl1,zahl2,ergebnis,lang); break; case '3':mul(zahl1,zahl2,ergebnis,lang); break; case '4':div(zahl1,zahl2,ergebnis,rest,lang); } printf("\nErgebnis:\n"); if(c=='3') ausgabe(ergebnis,lang*2); else ausgabe(ergebnis,lang); if(c=='4'){ printf("\nRest:\n"); ausgabe(rest,lang); } printf("\n\nWollen Sie den Vorgang wiederholen?"); printf("\n(1)Ja"); printf("\n(2)Menue"); printf("\n(3)Hilfe"); printf("\n(0)Ende\n"); printf("< >\b\b"); i=0; do{ if(i) printf("\b\b< > Falsche Eingabe\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); c2=getche(); i=1; }while(c2<'0'||c2>'3'); system("cls"); }while(c2=='1'); } if(c=='5'||c2=='3') hilfe(); }while(c!='0'&&c2!='0'); }
-
und jetzt nochmal *einfach* bitte.
-
okay, nochmal, gaaaanz langsam.
Ich versuche einen Taschenrechner zu machen, dieser soll bis zu 60 stellige Zahlen Addieren, Subrahieren, Multiplizieren und Dividieren können. Diese Zahlen speichere ich Ziffernweise in Arrays (zahl1[60]), in der Form:
0000000000000000000000000...01234=1234
00000000000000000000000...0233333=233333
Addition, Subtraktion und Multiplikation haben super funktioniert. Aber die Division funzt ned. Ich will das in dem System machen:
1234:2
Ich nehme die vorderste Stelle, das ist also eine null, weil sie ja wie oben abgespeichert sind und überprüfe ob sie größer der zu Dividierende Zahl ist.
Dadurch das 0 kleiner 2 ist, geht er zur nächsten Ziffer, diese eine Null ist, usw.Bis er zur 1 kommt. Er speichert dies mal in Rest.
0000...01
Dies ist aber noch immer kleiner 2. Also weiter.
Wir kommen zu 2. Jetzt muss mal der Rest verschoben werden.
0000...010
Jetzt wird rest[lang-1]=2 gesetzt.
0000...012
Jetzt ist sie größer als 2. Also wird solange subtrahiert und ergebniss[derzeitige Stelle der 1. Zahl]++ gemacht, bis sie wieder kleiner der zu dividierende Zahl ist. Also:
0000...0120000...002
__________ erg: 0000...0100
0000...0100000...002
__________ erg: 0000...0200
0000...008
usw.Und das ganze wird wieder wiederholt. Die Subtraktion funktioniert. Die Division sollte funzen. Aber es tut nicht, Beim Rest kommt ein Blödsinn raus, beim Ergebnis ebenfalls, alle Zahlen sind korrekt, alles initialisiert...
Aber schaut selbst:void div(const int *z1, const int *z2, int *erg, int*rest, int lang){ int i,j; for(i=0;i<lang;i++){ rest[lang-1]=z1[i]; while(a_gleich_b(rest,z2,lang)>0){ sub(rest,z2,rest,lang); erg[i]++; } for(j=1;j<lang;j++) rest[j-1]=rest[j]; } }//div ende
Das ist die Funktion Division. Sie verwendet 2 weitere Funktionen:
void sub(const int *z1, const int *z2, int *erg, int lang){ int i, h=a_gleich_b(z1,z2,lang); if(h>0){ for(i=lang-1;i>=0;i--){ erg[i]+=z1[i]-z2[i]; if(erg[i]<0){ erg[i-1]-=1; erg[i]+=10; } } } if(h<0){ for(i=lang-1;i>=0;i--){ erg[i]+=z2[i]-z1[i]; if(erg[i]<0){ erg[i-1]-=1; erg[i]+=10; } } for(i=0;erg[i]=='\0'&&i<lang;i++) ; erg[i]*=-1; } }//sub ende
und
int a_gleich_b(const int *z1, const int *z2, int lang){ int i, hilf=0; for(i=0;i<lang&&hilf==0;i++){ hilf=z1[i]-z2[i]; } return hilf; }//a_gleich_b ende
sub ist für die Subtraktion zuständig. Sie sollte tadellos funktionieren, ich hab sie ausführlich getestet.
a_gleich_b schaut welches Feld größer ist. Sie gibt eine einstellige positive Zahl zurück wenn z1 größer z2, 0 wenn sie gleich sind und eine einstellige negative Zahl zurück wenn z1 kleiner z2 ist.
Ich hab echt schon keine Ahnung mehr wo der Fehler ist... Aber schaut selbst...
-
Hier als Beispiel:
Division Geben Sie die erste Zahl ein 2123412 Geben Sie die zweite Zahl ein 123 Ergebnis: 6130100 Rest: -2147483636-2147483564-2147483636-2147483564-2147483636-2147483564-2147483636-21 47483564-2147483636-2147483564-2147483636-2147483564-2147483636-2147483564-21474 83636-2147483564-2147483636-2147483564-2147483636-2147483564-2147483636-21474835 64-2147483636-2147483564-2147483636-2147483564-2147483636-2147483564-2147483636- 2147483564-2147483636-2147483564-2147483636-2147483564-2147483636-2147483564-214 7483636-2147483564-2147483636-2147483564-2147483636-2147483564-2147483636-214748 3564-2147483636-2147483564-2147483636-2147483564-2147483636-2147483564-214748363 6-10737417261073741742-214748358876345122 Wollen Sie den Vorgang wiederholen? (1)Ja (2)Menue (3)Hilfe (0)Ende < >
Ach ja, kleine Bemerkung: isdigit ist ein Befehl von ctype.h
return a nonzero (true) result if it satisfies the following conditions. If not, then 0 (false) is returned.
int isdigit(int character);
isdigit a digit (0 to 9)
-
in div() lass dir nach jedem schritt alle aenderungen ausgeben.
-
Fehler gefunden.
Ich hab die Variable Rest problematischer Weise so bearbeitet in der Subtraktion das da immer eine andere Zahl subtrahiert wird, dadurch hab ich dann eine zweier potenz erhalten, diese verursacht hat, das ich int overflow hatte...