bigInteger cnp(unsigned long n, unsigned long p) { /* Factorial need unsigned long int */ if(n>p) { /* Just the definition of cnp */ return quotientBigInt(factorial(n),mulBigInt(factorial(p),factorial(n-p))); } /* Or no result */ else { return NULL; } }
bigInteger lcmBigInt(bigInteger a, bigInteger b) { /* Declarations */ bigInteger result=NULL; result=malloc(sizeof(nb)); /* lcm(a,b) = (a * b) / gcd(a,b) */ result=quotientBigInt(mulBigInt(a,b),gcdBigInt(a,b)); result->sign=FALSE; return result; }
bigInteger factorial(unsigned long a) { /* Declarations */ Dlist tmp=malloc(sizeof(Element)); bigInteger result=malloc(sizeof(nb)); bigInteger temp=malloc(sizeof(nb)); unsigned long i,j; char string[11]; char stringr[11]; /* Need to be a unsigned long int */ if(a<0) { return NULL; } /* 0! = 1 */ else if(a==0) { tmp=insertTail(tmp,1); tmp=removeHead(tmp); result->absvalue=tmp; return result; } else { i=1; j=0; /* Make an array of chars with a */ while(a>=i) { string[j]=(a%(i*10)-a%i)/i+'0'; i*=10; j++; } /* Make a bgiInteger with that array */ for(i=0; i<j; i++) { stringr[i]=string[j-i-1]; } stringr[i]='\0'; result=newBigInteger(stringr); /* For k from 1 to a-i, do r=r*k */ for(i=a-1; i>0; i--) { tmp=NULL; tmp=insertTail(tmp,a-i); temp->absvalue=tmp; result=mulBigInt(result,temp); } return result; } }
bigInteger restBigInt(bigInteger a, bigInteger b) { /* Declarations */ bigInteger result=NULL; bigInteger quo=NULL; bigInteger mul=NULL; result=malloc(sizeof(nb)); quo=malloc(sizeof(nb)); mul=malloc(sizeof(nb)); /* a / b = q * b + r so r = a - (b * q) */ quo=quotientBigInt(a,b); mul=mulBigInt(b,quo); result=diffBigInt(a,mul); return result; }
int main(void) { int choice = 0, lastOpe = 0; unsigned long fact = 0; char *str = NULL; BigInteger biOne = NULL, biTwo = NULL, res = NULL, temp = NULL; do { choice = display_menu(); switch(choice) { case 1: clean_stdin(); str = new_str_of_big_int(1); biOne = newBigInteger(str); free(str); str = NULL; break; case 2: clean_stdin(); str = new_str_of_big_int(2); biTwo = newBigInteger(str); free(str); str = NULL; break; case 3: temp = fromBigIntegerToBigInteger(biOne); biOne = fromBigIntegerToBigInteger(biTwo); biTwo = fromBigIntegerToBigInteger(temp); break; case 4: lastOpe = '+'; res = sumBigInt(biOne, biTwo); break; case 5: lastOpe = '-'; res = diffBigInt(biOne, biTwo); break; case 6: lastOpe = '*'; res = mulBigInt(biOne, biTwo); break; case 7: printf("Enter the number :\t"); scanf("%lu", &fact); res = factorial(fact); printf("(%ld)! = ", fact); printBigInteger(res); break; case 8: printf("BigInteger 1 :\t"); printBigInteger(biOne); printf("BigInteger 2:\t"); printBigInteger(biTwo); if(lastOpe != 0) { printf("\n(1) %c (2) = ", lastOpe); printBigInteger(res); } break; } printf("\n"); }while (choice != 9); delete_big_int(biOne); delete_big_int(biTwo); delete_big_int(res); delete_big_int(temp); return 0; }
bigInteger quotientBigInt(bigInteger a, bigInteger b) { /* Declarations */ Dlist l=malloc(sizeof(Element)); Dlist m=malloc(sizeof(Element)); Dlist tmp=malloc(sizeof(Element)); bigInteger plop=malloc(sizeof(nb)); bigInteger temp=malloc(sizeof(nb)); bigInteger result=malloc(sizeof(nb)); int i=0,j=0, depart=0,k=0,compare,X=-1,n; int bsign=FALSE; int asign=FALSE; char* string=NULL; char* qr=NULL; /* No null bigInteger ? */ if(a!=NULL && b!= NULL) { l=a->absvalue; m=b->absvalue; } else { result=sumBigInt(result,0); return result; } /* No null bigInteger ? (bis) */ if(m->value == 0 && m->next==NULL) { tmp=insertTail(tmp,0); removeHead(tmp); result->absvalue=tmp; result->sign=FALSE; return result; } /* Store the signs of a and b, and remove them to the bigInteger to avoid issues with the other fonctions used into quotientBigInt */ asign=a->sign; a->sign=FALSE; bsign=b->sign; b->sign=FALSE; /* If b > a, result will be < 1, not a bigInteger in fact, so 0 */ if(compareBigInt(a,b) == -1 || isNull(b)) { a->sign=asign; if(!isNull(b)) { b->sign=bsign; } tmp=insertTail(tmp,0); removeHead(tmp); result->absvalue=tmp; result->sign=FALSE; return result; } /* Basic division ? */ if(l->value<=9999 && l->next==NULL) { if(asign==bsign) { result->sign=FALSE; } else { result->sign=TRUE; } a->sign=asign; b->sign=bsign; tmp=insertTail(tmp,l->value/m->value); tmp=removeHead(tmp); result->absvalue=tmp; return result; } /* Count the number of characters in a and b and store it into i and j */ while(m->next!=NULL) { i+=4; m=m->next; } if(m->value>999) { i+=4; } else if(m->value>99) { i+=3; } else if(m->value>9) { i+=2; } else { i+=1; } /* Dynamic allocation for the first number divided by b, we don't need more than the number of characters +1 in b */ string=malloc((i+1)*sizeof(char)); while(l->next!=NULL) { j+=4; l=l->next; } if(l->value>999) { j+=4; } else if(l->value>99) { j+=3; } else if(l->value>9) { j+=2; } else { j+=1; } /* Dynamic allocation for the quotient, can't be larger than a */ qr=malloc(j*sizeof(char)); /* i is the number of characters of b * We take the i first characters of a * Then we make an bigInteger with that */ l=a->absvalue; while(l->next!=NULL) { l=l->next; } /* First 4 figures's package */ depart=j%4; if(depart==3) { k+=3; string[2]=l->value%10+'0'; string[1]=(l->value%100-l->value%10)/10+'0'; string[0]=(l->value%1000-l->value%100)/100+'0'; l=l->prev; } else if(depart==2) { k+=2; string[1]=l->value%10+'0'; string[0]=(l->value%100-l->value%10)/10+'0'; l=l->prev; } else if(depart==1) { k+=1; string[0]=l->value%10+'0'; l=l->prev; } depart=i; /* All the others 4 figures' packages, except the last one */ while(depart-k>=0) { string[k+3]=l->value%10+'0'; string[k+2]=(l->value%100-l->value%10)/10+'0'; string[k+1]=(l->value%1000-l->value%100)/100+'0'; string[k]=(l->value-l->value%1000)/1000+'0'; k+=4; if(l->prev!=NULL) { l=l->prev; } } /* The last one */ if(k-i==3) { string[k]=l->value%10+'0'; } else if(k-i==2) { string[k+1]=l->value%10+'0'; string[k]=(l->value%100-l->value%10)/10+'0'; } else if(k-i==1) { string[k+2]=l->value%10+'0'; string[k+1]=(l->value%100-l->value%10)/10+'0'; string[k]=(l->value%1000-l->value%100)/100+'0'; } /* Don't forget to close the string */ string[i]='\0'; plop=newBigInteger(string); /* Our bigInteger is ready */ /* If our new biginteger is < b, we need to take one more figure from a */ if(compareBigInt(plop,b)==-1) { tmp=NULL; tmp=insertTail(tmp,10); temp->absvalue=tmp; plop=mulBigInt(plop,temp); X=getNumberN(a,j-i); tmp=NULL; tmp=insertTail(tmp,X); temp->absvalue=tmp; plop=sumBigInt(plop,temp); i++; } i--; n=0; /* Compute the soustraction, like in primary school */ while(j-i>0) { i++; k=0; compare=0; /* How many times can I put the quotient ? */ while(compare>=0 && k<10) { k++; tmp=NULL; tmp=insertTail(tmp,k); temp->absvalue=tmp; temp=mulBigInt(b,temp); compare=compareBigInt(plop,temp); } k--; /* Store the figures of the quotient into an array of char */ tmp=NULL; tmp=insertTail(tmp,k); temp->absvalue=tmp; temp=mulBigInt(b,temp); qr[n]=k+'0'; n++; plop=diffBigInt(plop,temp); tmp=NULL; tmp=insertTail(tmp,10); temp->absvalue=tmp; plop=mulBigInt(plop,temp); /* Go down the next number */ if(j-i>0) { X=getNumberN(a,j-i); } tmp=NULL; tmp=insertTail(tmp,X); temp->absvalue=tmp; plop=sumBigInt(plop,temp); } /* Close the string */ qr[n]='\0'; /* Build the result bigInteger */ result=newBigInteger(qr); a->sign=asign; b->sign=bsign; /* Put the right sign */ if(a->sign==b->sign) { result->sign=FALSE; } else { result->sign=TRUE; } return result; }