Created
March 20, 2010 00:09
-
-
Save bloopletech/338338 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include "bigint.h" | |
/* this library provides for a bigint type, which can hold numbers of an unlimited length. | |
You can add them together as well.*/ | |
/*this function allocates & returns a bigint struct*/ | |
//given a bigint that is _already_ allocated, initialize it with zero. | |
void newnum(bigint* num) | |
{ | |
num->number = (digit*)malloc(1); | |
num->number[0] = 0; | |
num->length = 1; | |
} | |
//given a bigint that is _already_ allocated, | |
//and given a number string, allocate the bigint | |
void newnumf(bigint* num, char* numb) | |
{ | |
int numbl = strlen(numb); | |
digit* out = (digit*)malloc(numbl); | |
for(int i = 0; i < numbl; i++) | |
{ | |
out[i] = numb[i] - CHARZERO_ABOVEINTZERO; | |
} | |
num->number = out; | |
num->length = numbl; | |
} | |
//this function allocates and returns a bigint pointer, with the number numb allocated | |
bigint* newnumc(char* numb) | |
{ | |
//allocate storage for the bigint | |
bigint* num = (bigint*)malloc(sizeof(bigint)); | |
int numbl = strlen(numb); | |
int numbll = numbl - 1; | |
//allocate storage for the number, in the right length | |
digit* out = (digit*)malloc(numbl); | |
for(int i = 0; i < numbl; i++) | |
{ | |
out[i] = numb[numbll - i] - CHARZERO_ABOVEINTZERO; | |
} | |
num->number = out; | |
num->length = numbl; | |
//return the new bigint | |
return num; | |
} | |
//makes a deep copy of from, and put it in to | |
void numcpy(bigint* to, bigint* from) | |
{ | |
to->number = (digit*)realloc(to->number, from->length); | |
//copy from's number into to's number | |
int fl = from->length; | |
digit* tn = to->number; | |
digit* fn = from->number; | |
for(int i = 0; i < fl; i++) | |
{ | |
tn[i] = fn[i]; | |
} | |
//copy from's length into two's length | |
to->length = from->length; | |
} | |
//clear a bigint that was created by newnumc | |
void delnum(bigint* num) | |
{ | |
//free the bigint's number | |
free(num->number); | |
//free the bigint | |
free(num); | |
} | |
//adds a to b, and stores the result in result | |
void add(bigint* a, bigint* b, bigint* result) | |
{ | |
//store the length of ac and bc | |
int al = a->length; | |
int bl = b->length; | |
int length = al; | |
if(bl > al) length = bl; | |
//allocate storage for the length of the result | |
int cl = length + 1; | |
//allocate space for a and b's number | |
digit* ac = a->number; | |
digit* bc = b->number; | |
//allocate space for the result | |
digit* out = (digit*)malloc(cl); | |
int temp = 0, carry = 0; | |
for(int i = 0; i < length; i++) | |
{ | |
if(i >= al) temp = bc[i] + carry; | |
else if(i >= bl) temp = ac[i] + carry; | |
else temp = ac[i] + bc[i] + carry; | |
if(temp > 9) | |
{ | |
carry = 1; | |
temp -= 10; | |
} | |
else | |
{ | |
carry = 0; | |
} | |
out[i] = temp; | |
} | |
//fix up the last digit of carry/the length of carry | |
if(carry == 0) | |
{ | |
out = (digit*)realloc(out, length); | |
result->length = length; | |
} | |
else | |
{ | |
out[length] = carry; | |
result->length = cl; | |
} | |
result->number = out; | |
} | |
//print out a bigint's value | |
void print(bigint* num) | |
{ | |
digit* numc = num->number; //NOT A CHAR ARRAY | |
int numl = num->length; | |
int numll = numl - 1; | |
char* out = (char*)malloc(numl + 1); | |
for(int i = 0; i < numl; i++) | |
{ | |
out[i] = numc[numll - i] + CHARZERO_ABOVEINTZERO; | |
} | |
out[numl] = '\0'; | |
puts(out); | |
free(out); | |
} | |
//print out a bigint's value | |
void fprint(bigint* num, FILE *file) | |
{ | |
digit* numc = num->number; //NOT A CHAR ARRAY | |
int numl = num->length; | |
int numll = numl - 1; | |
char* out = (char*)malloc(numl + 1); | |
for(int i = 0; i < numl; i++) | |
{ | |
out[i] = numc[numll - i] + CHARZERO_ABOVEINTZERO; | |
} | |
out[numl] = '\0'; | |
fputs(out, file); | |
putc('\n', file); | |
free(out); | |
} | |
/*void fbprint(bigint* num, FILE *file) | |
{ | |
digit* numc = num->number; //NOT A CHAR ARRAY | |
int numl = num->length; | |
int i = 0; | |
long whattowrite = 0; | |
while((numl - i) >= 10) | |
{ | |
whattowrite = (numc[i++] * 10^0) | |
+ (numc[i++] * 10^1) | |
+ (numc[i++] * 10^2) | |
+ (numc[i++] * 10^3) | |
+ (numc[i++] * 10^4) | |
+ (numc[i++] * 10^5) | |
+ (numc[i++] * 10^6) | |
+ (numc[i++] * 10^7) | |
+ (numc[i++] * 10^8) | |
+ (numc[i++] * 10^9) | |
+ whattowrite; | |
fwrite(whattowrite, sizeof(int), 1, file); | |
if(whattowrite > INT_MAX) | |
{ | |
whattowrite -= INT_MAX; | |
} | |
} | |
if((numl - i) == 9) | |
{ | |
whattowrite = (numc[i++] * 10^0) | |
+ (numc[i++] * 10^1) | |
+ (numc[i++] * 10^2) | |
+ (numc[i++] * 10^3) | |
+ (numc[i++] * 10^4) | |
+ (numc[i++] * 10^5) | |
+ (numc[i++] * 10^6) | |
+ (numc[i++] * 10^7) | |
+ (numc[i++] * 10^8) | |
+ whattowrite; | |
fwrite(whattowrite, sizeof(int), 1, file); | |
if(whattowrite > INT_MAX) | |
{ | |
whattowrite -= INT_MAX; | |
} | |
fwrite( | |
int numll = numl - 1; | |
char* out = (char*)malloc(numl + 1); | |
for(int i = 0; i < numl; i++) | |
{ | |
out[i] = numc[numll - i] + CHARZERO_ABOVEINTZERO; | |
} | |
out[numl] = '\0'; | |
fputs(out, file); | |
putc('\n', file); | |
free(out); | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//this is the difference between the ASCII code for 0 and the integer 0 | |
#define CHARZERO_ABOVEINTZERO 48 | |
//This define defines a single byte unsigned integer | |
//if your system uses a different type for this kind of integer, substitute it here | |
typedef unsigned char digit; | |
//the type digit* represents an array of digit s | |
typedef struct | |
{ | |
digit* number; ///this is a pointer to an array of digit s | |
int length; // this is the length of the arrat referenced by number | |
} bigint; | |
void newnum(bigint*); | |
void newnumf(bigint*, char*); | |
bigint* newnumc(char*); | |
void numcpy(bigint*, bigint*); | |
void delnum(bigint*); | |
void add(bigint*, bigint*, bigint*); | |
void print(bigint*); | |
void fprint(bigint*, FILE*); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#include "bigint.h" | |
#define MAX_INT_DIGITS 10 | |
#define MAX_LONG_DIGITS 20 | |
/*this function calculates the fibonacci sequence*/ | |
int main(int argc, char** argv) | |
{ | |
printf("WARNING: Calculating large numbers of iterations can take a long time (> 10 minutes).\n"); | |
printf("The output file can also grow very large. The output file for 100,000 iterations is ~1GB.\n"); | |
printf("This program will use ~100%% CPU time during calculation.\n"); | |
printf("The program does not check for errors while calculating.\n"); | |
printf("If an error occurs during calculation, the operation of this program is undefined.\n"); | |
/*this function uses the following method to calculate the fibonacci sequence: | |
a = 1, b = 1 | |
loop: | |
c = a + b //c[i] = c[i - 1] + c[i - 2] | |
a = b //c[i - 2] = c[i - 1] | |
b = c //c[i - 1] = c[i] | |
in each loop, this seuence adds the two numbers together and takes the summands and | |
their result, and moves them down the sequence. This sequence does not requre storage | |
of any more than the last two numbers in the sequence.*/ | |
//the user is asked to press a key at the end of the program. | |
//The read statement at the end has to store the result somewhere, | |
//so it's put in here. | |
char temp = 'a'; | |
//create 3 bigints: 2 for the summands, and one for the result | |
bigint* a = newnumc("1"); | |
bigint* b = newnumc("1"); | |
bigint* c = newnumc("0"); | |
//get how many iterations? the user wants | |
int size = 0; | |
if(argc == 2) | |
{ | |
size = atoi(argv[1]); | |
} | |
else if(argc == 4) | |
{ | |
a = newnumc(argv[1]); | |
b = newnumc(argv[2]); | |
size = atoi(argv[3]); | |
} | |
else | |
{ | |
printf("How many iterations do you want? "); | |
scanf("%i", &size); | |
} | |
char* fname = (char*)malloc(9 + MAX_INT_DIGITS + MAX_LONG_DIGITS + 1); | |
sprintf(fname, "fib-%i-%i.txt", size, time(NULL)); | |
FILE *file = fopen(fname, "w"); | |
//print the first two iterations of the fibonacci sequence | |
if(size == 1) | |
{ | |
fprint(a, file); | |
} | |
else if(size >= 2) | |
{ | |
fprint(a, file); | |
fprint(b, file); | |
} | |
//the program prints out the first two iterations separate from the rest | |
size -= 2; | |
//loop for the required number of iterations | |
int i = 0; | |
while(i < size) | |
{ | |
//add the summands together and store the result in c | |
add(a, b, c); | |
//print the result | |
fprint(c, file); | |
//move b and c down the sequence | |
//see description at the top for more information | |
numcpy(a, b); | |
numcpy(b, c); | |
i++; | |
} | |
//clear a, b, and the result | |
delnum(a); | |
delnum(b); | |
delnum(c); | |
fflush(file); | |
fclose(file); | |
free(fname); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
malloc
๐NULL
๐Everything else is good.