Big Number
A. First Edition
This is a sort of half-finished trial version and I highly suspect that I will continue on this small trial. It
all started by an enquiry of a new friend from China who is asking questions about numeric. For less than a week
I had some interest in this area and bought a book "numeric recipes in C++". But quite soon I lost my focus during
my travel to Guangzhou, Shenzhen which is considered to be one of most developed area in economy in China.
B.The problem
This problem should be very basic and common for any student in computer science who is interested in numeric
area. How to store and calculate huge numbers which is bigger than 64 bit?
C.The
idea of
programThe idea is truly intuitive. I just store all digit as its ASCII code and mimic all operations I learned in
primary school.
D.The major functions
.
E.Further improvement
I half-finished this before I boarded the train for Guangzhou and it is just for record purpose I keep this
trivial, half-finished project.
F.File listing
1. list.h
2. list.cpp
3. number.h
4. number.cpp
5. main.cpp
กก
file name: list.h
#include <stdio.h> #include <stdlib.h> const int DefaultLength=10; class List { private: char* list; int size; int counter; void expand(); public: void clear(){counter=0;} List(int initSize=DefaultLength); void add(char ch, bool atEnd=true); int count(){ return counter;} char& operator[](int index); char operator[](int index) const; void setSize(int theSize); void setCount(int theCount); };
กก
file name: list.cpp
#include "list.h" #include <string.h> #include <malloc.h> List::List(int initSize) { if (initSize<=0) { printf("size must be positive number\n"); initSize=DefaultLength; } counter=0; setSize(initSize); } void List::setCount(int theCount) { if (theCount<=size&&theCount>=0) { counter=theCount; } } void List::setSize(int theSize) { size=theSize; if ((list=(char*)malloc(size*sizeof(char)))==NULL) { printf("cannot alloc memory\n"); exit(1); } } void List::expand() { //char* temp; //this is for safe, you won't lose your old data even if there //is low memory error if ((list=(char*)realloc(list, size*2*sizeof(char)))==NULL) { printf("cannot realloc\n"); exit(1); } //memcpy(temp, list, size*sizeof(char)); //printf("new size=%d\n", _msize(list)); size*=2; //free(list); //list=temp; } void List::add(char ch, bool atEnd) { if (counter==size) { expand(); } if (atEnd) { list[counter]=ch; } else { //shift for (int i=counter; i>0; i--) { list[i]=list[i-1]; } list[0]=ch; } //always counter++; } char& List::operator [](int index) { if (index>=0) { return list[index]; } } char List::operator [](int index) const { if (index>=0&&index<counter) { return list[index]; } else { printf("index out of bound\n"); } }
กก
file name: bignumber.h
#include <stdio.h> #include <stdlib.h> #include "list.h" //typedef char Byte; class Number { private: List list; void addZero(int howMany); void scaling(short digit); int carryOn; //void clear(); public: void readFromFile(char* fileName); void display(); int count(); Number operator*(int scalar); Number& operator*(Number& other); Number operator+(Number& other); Number& operator=(Number& other); };
file name: bignumber.cpp
#include "bignumber.h" #include <math.h> const int DecimalModulo=10; void Number::readFromFile(char* fileName) { FILE* stream; char ch; if ((stream=fopen(fileName, "r"))==NULL) { printf("cannot open file %s\n", fileName); exit(1); } while (!feof(stream)) { ch=fgetc(stream); if (ch>='0'&&ch<='9') { list.add(ch); } else { if (!feof(stream)) { printf("bad file\n"); exit(1); } } } } int Number::count() { return list.count(); } void Number::display() { int length=count(); for (int i=0; i<length; i++) { printf("%c", list[i]); } printf("\n"); } Number Number::operator *(int scalar) { div_t result; int subTotal=scalar; short digit=0; int shiftNumber=0; Number temp, theResult; do { temp=*this; result=div(subTotal, DecimalModulo); digit=result.rem; temp.addZero(shiftNumber); temp.scaling(digit); shiftNumber++; subTotal=result.quot; theResult=theResult+temp; } while(subTotal!=0); return theResult; } //internal method void Number::scaling(short digit) { short myNumber, subTotal; /* if (digit==0) { return; } */ carryOn=0; for (int i=count()-1; i>=0; i--) { myNumber=list[i]-'0'; subTotal=myNumber*digit+carryOn; list[i]=subTotal%10+'0'; carryOn=subTotal/10; } if (carryOn>0) { list.add(carryOn+'0', false); } } void Number::addZero(int howMany) { for (int i=0; i<howMany; i++) { list.add('0'); } } Number& Number::operator =(Number& other) { list.clear(); for (int i=0; i<other.count(); i++) { list.add(other.list[i]); } return *this; } Number Number::operator +(Number& other) { int myLength=count(), otherLength=other.count(); int length=myLength>otherLength?myLength:otherLength; short first, second, subTotal; Number result; carryOn=0; result.list.setSize(length); for (int i=0; i<length; i++) { if (i>=myLength) { first=0; } else { first=list[myLength-1-i]-'0'; } if (i>=otherLength) { second=0; } else { second=other.list[otherLength-1-i]-'0'; } subTotal=first+second+carryOn; if (subTotal>=10) { subTotal-=10; carryOn=1; } else { carryOn=0; } result.list[length-1-i]=subTotal+'0'; } result.list.setCount(length); if (carryOn>0) { result.list.add('1', false); } return result; }
file name: main.cpp
#include <stdio.h> #include <stdlib.h> #include "bignumber.h" int main() { Number M, N, O; N.readFromFile("nick.txt"); printf("this is N\n "); N.display(); //M=N; O=N*180; printf("O=N*180\n"); O.display(); M=O+N; printf("M=O+N=\n"); M.display(); return 0; }
running result:
The content of input file "nick.txt" is like following:
12345678901234344353535233333333333333333333443436689797670
And the running result is something like following:
this is N
12345678901234344353535233333333333333333333443436689797670
O=N*180
2222222202222181983636342000000000000000000019818604163580600
M=O+N=
2234567881123416327989877233333333333333333353262040853378270
Press any key to continue
กก