F
fermineutron
I wrote a program to calculate factorials of large numbers. The long
precission integers are stores in arrays. When i specify the length of
these arrays larger than 16000 elements, each element is a long int,
the windows refuses to execute the program. More precicely the code
terminates as soon as it starts to execute. How can i overcome this
issue. Note, if array length is set smaller the code runs with no
problems.
Here is the code:
==========================Start Paste==========================
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define al 8024*8
#define base 1000
typedef long int IntegerArrayType;
struct AEI{
IntegerArrayType data[al];
long int digits;
};
void pack(IntegerArrayType i, struct AEI *N1);
void Aadd(struct AEI * A, struct AEI * B, struct AEI * C);
void Ambi(struct AEI * A, IntegerArrayType B, struct AEI * C);
void Lshift(struct AEI * A, IntegerArrayType B, struct AEI * C);
void Amult(struct AEI * A, struct AEI * B, struct AEI * C);
void AEIprintf(struct AEI * N1);
void AEIfprintf(FILE * fp, struct AEI * N1);
int main(void)
{
struct AEI N1, MO;
long i = 0, j = 0, ii, NUM;
FILE *ff;
while (i < al)
{
N1.data = 0;
MO.data = 0;
i++;
}
printf("Enter integer to Factorialize: ");
scanf("%ld", &NUM);
pack(1, &N1);
ff = fopen("Results.txt", "w");
printf("you entered: %ld", NUM);
i=1;
while(i < NUM )
{
ii = 1;
while (ii < al)
{
MO.data[ii] = 0;
ii++;
}
pack((i+1), &MO);
Amult(&N1, &MO, &N1);
printf("\nPogress: %d", i);
i++;
}
if(ff!=NULL){
fprintf(ff,"\n%d\n",i+1);
AEIfprintf(ff, &N1);
}
fclose(ff);
printf("\nPogress: 100%");
return 0;
}
void AEIprintf(struct AEI *N1){
double fieldLength;
double temp;
char format0[8];
char format1[8];
long j;
j = N1->digits-1;
fieldLength = log10(base);
temp = modf(fieldLength, &fieldLength);
format0[0] = '%';
format0[1] = fieldLength + 48;
format0[2] = 'd';
format0[3] = 0x00;
format1[0] = '%';
format1[1] = '0';
format1[2] = fieldLength + 48;
format1[3] = 'd';
format1[4] = 0x00;
printf(format0, N1->data[j]);
j--;
while (j >= 0)
{
printf(format1, N1->data[j]);
j--;
}
return;
}
void AEIfprintf(FILE * fp, struct AEI *N1){
long j = N1->digits-1;
double fieldLength, temp;
char format0[8], format1[8];
fieldLength = log10(base);
temp = modf(fieldLength, &fieldLength);
format0[0] = '%';
format0[1] = fieldLength + 48;
format0[2] = 'd';
format0[3] = 0x00;
format1[0] = '%';
format1[1] = '0';
format1[2] = fieldLength + 48;
format1[3] = 'd';
format1[4] = 0x00;
fprintf(fp,format0, N1->data[j]);
j--;
while (j >= 0){
fprintf(fp, format1, N1->data[j]);
j--;
}
return;
}
void pack(IntegerArrayType i, struct AEI * N1)
{
long t = 1, i1, j = 0;
while (t == 1){
i1 = i % base;
N1->data[j] = i1;
i = (i - i1) / base;
j++;
if (i == 0)
t = 0;
}
N1->digits=j;
return;
}
void Aadd(struct AEI *A, struct AEI *B, struct AEI *C){ /* C = A + B
*/
long carry = 0, result, i =0, d;
if(A->digits>B->digits){
d=A->digits;
}else{
d=B->digits;
}
while (i < d && i<al){
result = A->data + B->data + carry;
C->data = result % base;
carry = (result - result % base) / base;
i++;
}
if(carry!=0 && i<al){
C->data=carry;
d++;
}
if(i==al){
printf("\nAadd Array overflow");
}
C->digits=d;
return;
}
void Ambi(struct AEI *A, IntegerArrayType B, struct AEI *C){
/*C = A * B; B is integer; */
long carry = 0, result, i = 0, d;
d=A->digits;
while (i < d){
result = A->data * B + carry;
C->data = result % base;
carry = (result - result % base) / base;
i++;
}
if(carry!=0 && i<al){
C->data=carry;
d++;
}
if(i==al){
printf("\nAmbi Array overflow");
}
C->digits=d;
return;
}
void Lshift(struct AEI * A, IntegerArrayType B, struct AEI * C){
/*C = A LS B; B is integer; */
long i = 0;
while (i<A->digits && (i + B) < al){
C->data[i + B] = A->data;
i++;
}
if(i+B==al){
printf("\nArray overflow");
}
C->digits=A->digits+B;
return;
}
void Amult(struct AEI * A, struct AEI * B, struct AEI * C){
/*C = A * B; */
long i, ii;
struct AEI Temp, Temp1, ANS;
ii = 0;
while (ii < al){
ANS.data[ii] = 0;
ii++;
}
ANS.digits=0;
i = 0;
while (i < B->digits){
ii = 0;
while (ii < al){
Temp1.data[ii] = 0;
Temp.data[ii] = 0;
ii++;
}
Temp.digits=0;
Temp1.digits=0;
Lshift(A, i, &Temp);
if(B->data!=0){
Ambi(&Temp, B->data, &Temp1);
Aadd(&Temp1, &ANS, &ANS);
}
i++;
}
i = 0;
while(i<al){
C->data=ANS.data;
i++;
}
C->digits=ANS.digits;
return;
}
=========================End Paste=============================
thanks ahead.
precission integers are stores in arrays. When i specify the length of
these arrays larger than 16000 elements, each element is a long int,
the windows refuses to execute the program. More precicely the code
terminates as soon as it starts to execute. How can i overcome this
issue. Note, if array length is set smaller the code runs with no
problems.
Here is the code:
==========================Start Paste==========================
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define al 8024*8
#define base 1000
typedef long int IntegerArrayType;
struct AEI{
IntegerArrayType data[al];
long int digits;
};
void pack(IntegerArrayType i, struct AEI *N1);
void Aadd(struct AEI * A, struct AEI * B, struct AEI * C);
void Ambi(struct AEI * A, IntegerArrayType B, struct AEI * C);
void Lshift(struct AEI * A, IntegerArrayType B, struct AEI * C);
void Amult(struct AEI * A, struct AEI * B, struct AEI * C);
void AEIprintf(struct AEI * N1);
void AEIfprintf(FILE * fp, struct AEI * N1);
int main(void)
{
struct AEI N1, MO;
long i = 0, j = 0, ii, NUM;
FILE *ff;
while (i < al)
{
N1.data = 0;
MO.data = 0;
i++;
}
printf("Enter integer to Factorialize: ");
scanf("%ld", &NUM);
pack(1, &N1);
ff = fopen("Results.txt", "w");
printf("you entered: %ld", NUM);
i=1;
while(i < NUM )
{
ii = 1;
while (ii < al)
{
MO.data[ii] = 0;
ii++;
}
pack((i+1), &MO);
Amult(&N1, &MO, &N1);
printf("\nPogress: %d", i);
i++;
}
if(ff!=NULL){
fprintf(ff,"\n%d\n",i+1);
AEIfprintf(ff, &N1);
}
fclose(ff);
printf("\nPogress: 100%");
return 0;
}
void AEIprintf(struct AEI *N1){
double fieldLength;
double temp;
char format0[8];
char format1[8];
long j;
j = N1->digits-1;
fieldLength = log10(base);
temp = modf(fieldLength, &fieldLength);
format0[0] = '%';
format0[1] = fieldLength + 48;
format0[2] = 'd';
format0[3] = 0x00;
format1[0] = '%';
format1[1] = '0';
format1[2] = fieldLength + 48;
format1[3] = 'd';
format1[4] = 0x00;
printf(format0, N1->data[j]);
j--;
while (j >= 0)
{
printf(format1, N1->data[j]);
j--;
}
return;
}
void AEIfprintf(FILE * fp, struct AEI *N1){
long j = N1->digits-1;
double fieldLength, temp;
char format0[8], format1[8];
fieldLength = log10(base);
temp = modf(fieldLength, &fieldLength);
format0[0] = '%';
format0[1] = fieldLength + 48;
format0[2] = 'd';
format0[3] = 0x00;
format1[0] = '%';
format1[1] = '0';
format1[2] = fieldLength + 48;
format1[3] = 'd';
format1[4] = 0x00;
fprintf(fp,format0, N1->data[j]);
j--;
while (j >= 0){
fprintf(fp, format1, N1->data[j]);
j--;
}
return;
}
void pack(IntegerArrayType i, struct AEI * N1)
{
long t = 1, i1, j = 0;
while (t == 1){
i1 = i % base;
N1->data[j] = i1;
i = (i - i1) / base;
j++;
if (i == 0)
t = 0;
}
N1->digits=j;
return;
}
void Aadd(struct AEI *A, struct AEI *B, struct AEI *C){ /* C = A + B
*/
long carry = 0, result, i =0, d;
if(A->digits>B->digits){
d=A->digits;
}else{
d=B->digits;
}
while (i < d && i<al){
result = A->data + B->data + carry;
C->data = result % base;
carry = (result - result % base) / base;
i++;
}
if(carry!=0 && i<al){
C->data=carry;
d++;
}
if(i==al){
printf("\nAadd Array overflow");
}
C->digits=d;
return;
}
void Ambi(struct AEI *A, IntegerArrayType B, struct AEI *C){
/*C = A * B; B is integer; */
long carry = 0, result, i = 0, d;
d=A->digits;
while (i < d){
result = A->data * B + carry;
C->data = result % base;
carry = (result - result % base) / base;
i++;
}
if(carry!=0 && i<al){
C->data=carry;
d++;
}
if(i==al){
printf("\nAmbi Array overflow");
}
C->digits=d;
return;
}
void Lshift(struct AEI * A, IntegerArrayType B, struct AEI * C){
/*C = A LS B; B is integer; */
long i = 0;
while (i<A->digits && (i + B) < al){
C->data[i + B] = A->data;
i++;
}
if(i+B==al){
printf("\nArray overflow");
}
C->digits=A->digits+B;
return;
}
void Amult(struct AEI * A, struct AEI * B, struct AEI * C){
/*C = A * B; */
long i, ii;
struct AEI Temp, Temp1, ANS;
ii = 0;
while (ii < al){
ANS.data[ii] = 0;
ii++;
}
ANS.digits=0;
i = 0;
while (i < B->digits){
ii = 0;
while (ii < al){
Temp1.data[ii] = 0;
Temp.data[ii] = 0;
ii++;
}
Temp.digits=0;
Temp1.digits=0;
Lshift(A, i, &Temp);
if(B->data!=0){
Ambi(&Temp, B->data, &Temp1);
Aadd(&Temp1, &ANS, &ANS);
}
i++;
}
i = 0;
while(i<al){
C->data=ANS.data;
i++;
}
C->digits=ANS.digits;
return;
}
=========================End Paste=============================
thanks ahead.