当前手机最多支持9位数的运算,电脑计算器最多支持16位数运算
(1)此程序生成随机数的运算理论上可多至成千上万位
(2)自行输入数据,每个数最大可到unsigned long long的最大值18446744073709551615,支持19位,部分20位数的加减乘除运算
负数运算目前不支持,还在改进中
以顺序表存储大数,0下标先不存储(留作符号位),将数的高位放在高下标,低位放在低下标,(如果数的高位放在顺序表的低下标,进位、对位、借位皆难操作,降低运算效率)输出时将顺序表由高到低位依次输出,即为输入或者求得的大数
代码如下
//utili.h
#pragma once
#include<iostream>
#include<assert.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
using namespace std;
typedef unsigned char u_char;
typedef unsigned long u_long;
typedef unsigned long long u_long_long;
//Seqlist.h
#pragma once
#include"utili.h"
class BigInt;
template<class Type>
class SeqList
{
friend class BigInt;
public:
SeqList(size_t sz = DEFAULT_SIZE);
SeqList(const SeqList<Type> &bt);
SeqList& operator=(const SeqList<Type> &st);
~SeqList();
public:
typedef Type& reference;
typedef const Type& const_reference;
public:
void push_back(const Type &x);
void push_front(const Type &x);
void pop_back();
void pop_front();
reference front();
reference back();
void clear();
const_reference back()const;
const_reference front()const;
size_t size()const;
public:
reference operator[](int pos);
const_reference operator[](int pos)const;
public:
bool Inc()
{
capacity += INC_SIZE;
Type *new_base = new Type[capacity+1];
if(NULL == new_base)
{
cout<<"Out Of Memory."<<endl;
//exit(1);
return false;
}
memset(new_base, 0, sizeof(Type)*(capacity+1));
memcpy(new_base, base, sizeof(Type)*(capacity-INC_SIZE+1));
delete []base;
base = new_base;
return true;
}
private:
enum{DEFAULT_SIZE = 10, INC_SIZE = 5};
Type *base;
size_t capacity;
size_t len;
};
///
template<class Type>
SeqList<Type>::SeqList(size_t sz)
{
capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;
base = new Type[capacity+1];
memset(base, 0, sizeof(Type) * (capacity+1));
len = 0;
}
template<class Type>
SeqList<Type>::SeqList(const SeqList<Type> &bt)
{
capacity = bt.capacity;
base = new Type[sizeof(Type)*(capacity+1)];
memset(base, 0, sizeof(Type)*(capacity+1));
memcpy(base, bt.base, sizeof(Type)*(bt.len+1));
len = bt.len;
}
//bt = bt1;
template<class Type>
SeqList<Type>& SeqList<Type>::operator=(const SeqList<Type> &st)
{
if(this != &st)
{
if(capacity < st.len)
{
delete []base;
base = new Type[st.capacity+1];
capacity = st.capacity;
}
memcpy(base, st.base, sizeof(Type)*(st.len+1));
len = st.len;
}
return *this;
}
template<class Type>
SeqList<Type>::~SeqList()
{
delete []base;
base = NULL;
capacity = len = 0;
}
template<class Type>
void SeqList<Type>::push_back(const Type &x)
{
//assert(len < capacity);
if(len>=capacity && !Inc())
return;
base[++len] = x;
}
template<class Type>
void SeqList<Type>::push_front(const Type &x)
{
//assert(len < capacity);
if(len>=capacity && !Inc())
return;
for(int i=++len; i>1; --i)
{
base[i] = base[i-1];
}
base[1] = x;
}
template<class Type>
void SeqList<Type>::pop_back()
{
assert(len > 0);
--len;
}
template<class Type>
void SeqList<Type>::pop_front()
{
assert(len > 0);
for(int i=1; i<len; ++i)
{
base[i] = base[i+1];
}
--len;
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::front()
{
assert(len > 0);
return base[1];
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::back()
{
assert(len > 0);
return base[len];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::front()const
{
assert(len > 0);
return base[1];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::back()const
{
assert(len > 0);
return base[len];
}
template<class Type>
size_t SeqList<Type>::size()const
{
return len;
}
template<class Type>
void SeqList<Type>::clear()
{
len = 0;
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::operator[](int pos)
{
assert(pos>=1 && pos<=len);
return base[pos];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::operator[](int pos)const
{
assert(pos>=1 && pos<=len);
return base[pos];
}
//BigInt.h
#pragma once
#include"utili.h"
#include"SeqList.h"
class BigInt;
ostream& operator<<(ostream &out, const BigInt &bt);
class BigInt
{
friend ostream& operator<<(ostream &out, const BigInt &bt);
public:
BigInt(u_long_long value = 0);
BigInt& operator=(u_long value);
public:
void LoadData(size_t sz);
void PrintData()const;
public:
void Clear();
void BigIntCopy(char *buf, size_t len, size_t &pos);
public:
u_char back()const;
void pop_back();
size_t size()const;
void clear();
void clear_head_zero();
void push_back(u_char x);
void push_front(u_char x);
public:
static u_char AddItem(u_char a, u_char b, u_char &sign);
static u_char SubItem(u_char a, u_char b, u_char &sign);
static void MulItem(BigInt &bt, const BigInt &bt1, u_char x);
static void AddMove(BigInt &bt, const BigInt &bt1, int offset);
public:
static void Add(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Sub(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Mul(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Div(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Mod(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Square(BigInt &bt, const BigInt &bt1);//bt = bt1^2;
public:
u_char& operator[](int pos);
const u_char& operator[](int pos)const;
public:
BigInt operator+(const BigInt &bt);
BigInt operator-(const BigInt &bt);
BigInt operator*(const BigInt &bt);
BigInt operator/(const BigInt &bt);
BigInt operator%(const BigInt &bt);
public:
BigInt& operator++();
BigInt operator++(int);
BigInt& operator--();
BigInt operator--(int);
public:
BigInt& operator+=(const BigInt &bt);
BigInt& operator-=(const BigInt &bt);
BigInt& operator*=(const BigInt &bt);
BigInt& operator/=(const BigInt &bt);
BigInt& operator%=(const BigInt &bt);
public:
bool operator>(const BigInt &bt)const;
bool operator<(const BigInt &bt)const;
bool operator>=(const BigInt &bt)const;
bool operator<=(const BigInt &bt)const;
bool operator==(const BigInt &bt)const;
bool operator!=(const BigInt &bt)const;
public:
bool operator>(u_long x)const;
bool operator&(u_long x);
private:
SeqList<u_char> big;
};
//BigInt.cpp
#include"BigInt.h"
ostream& operator<<(ostream &out, const BigInt &bt)
{
for(size_t i=bt.size(); i>=1; --i)
{
out<<(int)bt[i];
}
return out;
}
BigInt::BigInt(u_long_long value)
{
if(value == 0)
{
push_back(0);
}
else
{
while(value > 0)
{
push_back(value % 10);
value /= 10;
}
}
}
//bt = 123
BigInt& BigInt::operator=(u_long value)
{
(*this).clear();
if(value == 0)
{
push_back(0);
}
else
{
while(value > 0)
{
push_back(value % 10);
value /= 10;
}
}
return *this;
}
/
void BigInt::LoadData(size_t sz)
{
clear();
srand(time(NULL));
for(int i=0; i<sz; ++i)
{
big.push_back(rand()%10);
}
clear_head_zero();
}
void BigInt::PrintData()const
{
for(int i=size(); i>=1; --i)
{
cout<<(int)big[i];
}
cout<<endl;
}
void BigInt::Clear()
{
big.clear();
}
void BigInt::BigIntCopy(char *buf, size_t len, size_t &pos)
{
if(pos == 0)
{
memcpy(buf,big.base,1); //copy 0 index
pos++;
}
memcpy(buf,big.base+pos, len);
}
u_char BigInt::back()const
{
return big.back();
}
void BigInt::pop_back()
{
big.pop_back();
}
size_t BigInt::size()const
{return big.size();}
void BigInt::clear()
{big.clear();}
void BigInt::push_back(u_char x)
{
big.push_back(x);
}
void BigInt::push_front(u_char x)
{
big.push_front(x);
}
void BigInt::clear_head_zero()
{
while(size()>0 && *this!=0 && (*this).back() == 0)
{
pop_back();
}
}
u_char& BigInt::operator[](int pos)
{return big[pos];}
const u_char& BigInt::operator[](int pos)const
{return big[pos];}
bool BigInt::operator>(const BigInt &bt)const
{
if(size() > bt.size())
return true;
else if(size() < bt.size())
return false;
size_t i = size();
while(i >= 1)
{
if((*this)[i] > bt[i])
return true;
else if((*this)[i] < bt[i])
return false;
--i;
}
return false;
}
bool BigInt::operator<=(const BigInt &bt)const
{
return !(*this > bt);
}
bool BigInt::operator<(const BigInt &bt)const
{
if(size() < bt.size())
return true;
else if(size() > bt.size())
return false;
size_t i = size();
while(i >= 1)
{
if((*this)[i] < bt[i])
return true;
else if((*this)[i] > bt[i])
return false;
--i;
}
return false;
}
bool BigInt::operator>=(const BigInt &bt)const
{
return !(*this < bt);
}
bool BigInt::operator==(const BigInt &bt)const
{
if(size() != bt.size())
return false;
size_t i = 1;
while(i <= size())
{
if((*this)[i] != bt[i])
return false;
++i;
}
return true;
}
bool BigInt::operator!=(const BigInt &bt)const
{
return !(*this == bt);
}
bool BigInt::operator>(u_long x)const
{
BigInt tmp(x);
return *this > tmp;
}
BigInt& BigInt::operator++()
{
u_char sign = 1;
size_t i = 1;
while(sign>0 && i<=size())
{
(*this)[i] = AddItem((*this)[i], 0, sign);
++i;
}
if(sign > 0)
push_back(sign);
return *this;
}
BigInt BigInt::operator++(int)
{
BigInt tmp = *this;
++*this;
return tmp;
}
BigInt& BigInt::operator--()
{
assert(*this > 0);
u_char sign = 1;
size_t i = 1;
while(sign>0 && i<=size())
{
(*this)[i] = SubItem((*this)[i], 0, sign);
++i;
}
clear_head_zero();
return *this;
}
BigInt BigInt::operator--(int)
{
BigInt tmp = *this;
--*this;
return tmp;
}
BigInt& BigInt::operator+=(const BigInt &bt)
{
u_char sign = 0;
size_t i=1, j=1;
while(i<=size() && j<=bt.size())
{
(*this)[i] = AddItem((*this)[i], bt[j], sign);
++i;
++j;
}
while(sign>0 && i<=size())
{
(*this)[i] = AddItem((*this)[i], 0, sign);
++i;
}
while(j <= bt.size())
{
u_char sum = AddItem(0, bt[j], sign);
push_back(sum);
++j;
}
if(sign > 0)
push_back(sign);
return *this;
}
BigInt& BigInt::operator-=(const BigInt &bt)
{
assert(*this >= bt);
if(*this == bt)
{
*this = 0;
return *this;
}
else
{
u_char sign = 0;
size_t i=1, j=1;
while(i<=size() && j<=bt.size())
{
(*this)[i] = SubItem((*this)[i], bt[j], sign);
++i;
++j;
}
while(sign>0 && i<=size())
{
(*this)[i] = SubItem((*this)[i], 0, sign);
++i;
}
}
return *this;
}
BigInt& BigInt::operator*=(const BigInt &bt)
{
BigInt tmp;
BigInt::Mul(tmp, *this, bt);
*this = tmp;
return *this;
}
BigInt& BigInt::operator/=(const BigInt &bt)
{
BigInt tmp;
BigInt::Div(tmp, *this, bt);
*this = tmp;
return *this;
}
BigInt& BigInt::operator%=(const BigInt &bt)
{
BigInt tmp;
BigInt::Mod(tmp, *this, bt);
*this = tmp;
return *this;
}
BigInt BigInt::operator+(const BigInt &bt)
{
BigInt tmp;
BigInt::Add(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator-(const BigInt &bt)
{
BigInt tmp;
BigInt::Sub(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator*(const BigInt &bt)
{
BigInt tmp;
BigInt::Mul(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator/(const BigInt &bt)
{
BigInt tmp;
BigInt::Div(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator%(const BigInt &bt)
{
BigInt tmp;
BigInt::Mod(tmp, *this, bt);
return tmp;
}
bool BigInt::operator&(u_long x)
{
BigInt tmp(2);
BigInt ans = *this % tmp;
return ans==1;
}
u_char BigInt::AddItem(u_char a, u_char b, u_char &sign)
{
u_char sum = a + b + sign;
if(sum >= 10)
{
sum -= 10;
sign = 1;
}
else
sign = 0;
return sum;
}
void BigInt::Add(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt.clear();
u_char sum, sign = 0;
size_t i=1, j=1;
while(i<=bt1.size() && j<=bt2.size())
{
sum = AddItem(bt1[i],bt2[j],sign);
bt.push_back(sum);
++i;
++j;
}
while(i <= bt1.size())
{
sum = AddItem(bt1[i], 0, sign);
bt.push_back(sum);
++i;
}
while(j <= bt2.size())
{
sum = AddItem(0, bt2[j], sign);
bt.push_back(sum);
++j;
}
if(sign > 0)
bt.push_back(sign);
}
u_char BigInt::SubItem(u_char a, u_char b, u_char &sign)
{
u_char sub;
if(a >= b+sign)
{
sub = a - b - sign;
sign = 0;
}
else
{
sub = a + 10 - b - sign;
sign = 1;
}
return sub;
}
void BigInt::Sub(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt.clear();
if(bt1 < bt2)
return;
if(bt1 == bt2)
bt = 0;
u_char sub, sign = 0;
size_t i=1, j=1;
while(i<=bt1.size() && j<=bt2.size())
{
sub = SubItem(bt1[i], bt2[j], sign);
bt.push_back(sub);
++i;
++j;
}
while(i<=bt1.size())
{
sub = SubItem(bt1[i], 0, sign);
bt.push_back(sub);
++i;
}
bt.clear_head_zero();
}
void BigInt::MulItem(BigInt &bt, const BigInt &bt1, u_char x)
{
u_char mul, sign = 0;
size_t i = 1;
while(i <= bt1.size())
{
mul = bt1[i] * x + sign;
if(mul >= 10)
{
sign = mul / 10;
mul %= 10;
}
else
sign = 0;
bt.push_back(mul);
++i;
}
if(sign > 0)
bt.push_back(sign);
}
void BigInt::AddMove(BigInt &bt, const BigInt &bt1, int offset)
{
u_char sign = 0;
size_t i = offset;
size_t j = 1;
while(i<=bt.size() && j<=bt1.size())
{
bt[i] = AddItem(bt[i], bt1[j], sign);
++i;
++j;
}
while(sign>0 && i<=bt.size())
{
bt[i] = AddItem(bt[i], 0, sign);
++i;
}
while(j <= bt1.size())
{
u_char sum = AddItem(0, bt1[j], sign);
bt.push_back(sum);
++j;
}
if(sign > 0)
bt.push_back(sign);
}
void BigInt::Mul(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt.Clear();
BigInt tmp;
for(size_t i=1; i<=bt2.size(); ++i)
{
tmp.clear();
MulItem(tmp, bt1, bt2[i]);
AddMove(bt, tmp, i);
}
}
void BigInt::Div(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt = 0;
if(bt1 < bt2)
bt = 0;
else if(bt1 == bt2)
bt = 1;
else
{
size_t bt1_len = bt1.size();
size_t bt2_len = bt2.size();
int k = bt1_len - bt2_len;
BigInt btd;
btd.clear();
for(size_t i=1; i<=bt2.size(); ++i)
{
btd.push_back(bt1[i+k]);
}
u_char div = 0;
while(k >= 0)
{
while(btd >= bt2)
{
btd -= bt2;
div++;
btd.clear_head_zero();
}
bt.push_front(div);
div = 0;
if(k > 0)
btd.push_front(bt1[k]);
--k;
}
bt.clear_head_zero();
}
}
void BigInt::Mod(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt = 0;
if(bt1 < bt2)
bt = bt1;
else if(bt1 == bt2)
bt = 0;
else
{
size_t bt1_len = bt1.size();
size_t bt2_len = bt2.size();
int k = bt1_len - bt2_len;
BigInt btd;
btd.clear();
for(size_t i=1; i<=bt2.size(); ++i)
{
btd.push_back(bt1[i+k]);
}
while(k >= 0)
{
while(btd >= bt2)
{
btd -= bt2;
btd.clear_head_zero();
}
if(k > 0)
btd.push_front(bt1[k]);
--k;
}
bt = btd;
bt.clear_head_zero();
}
}
void BigInt::Square(BigInt &bt, const BigInt &bt1)
{
BigInt::Mul(bt, bt1, bt1);
}
验证程序正确性,因为计算器最多只能计算16位数,随机生成了一个16位数和一个15位数
#include<iostream>
#include<windows.h>
#include"BigInt.h"
using namespace std;
void main()
{
BigInt bt, bt1, bt2;
bt1.LoadData(16);
cout<<"bt1 = "<<bt1<<endl;
Sleep(1000);
bt2.LoadData(15);
cout<<"bt2 = "<<bt2<<endl;
BigInt::Add(bt,bt1,bt2);
cout<<"bt=bt1+bt2= "<<bt<<endl;
BigInt::Sub(bt,bt1,bt2);
cout<<"bt=bt1-bt2= "<<bt<<endl;
BigInt::Mul(bt,bt1,bt2);
cout<<"bt=bt1*bt2= "<<bt<<endl;
BigInt::Div(bt,bt1,bt2);
cout<<"bt=bt1/bt2= "<<bt<<endl;
}
运行结果如下:
计算器算得结果如下:
再来看两个大整数给定值的计算结果,为了展示结果第二个数稍小
#include<iostream>
#include<windows.h>
#include"BigInt.h"
using namespace std;
void main()
{
BigInt bt, bt1(11111111111111111111), bt2(100);
cout<<"bt1 = "<<bt1<<endl;
cout<<"bt2 = "<<bt2<<endl;
BigInt::Add(bt,bt1,bt2);
cout<<"bt=bt1+bt2= "<<bt<<endl;
BigInt::Sub(bt,bt1,bt2);
cout<<"bt=bt1-bt2= "<<bt<<endl;
BigInt::Mul(bt,bt1,bt2);
cout<<"bt=bt1*bt2= "<<bt<<endl;
BigInt::Div(bt,bt1,bt2);
cout<<"bt=bt1/bt2= "<<bt<<endl;
}
后续将会改进程序使之能进行更多运算。