BigNumber.h
#ifndef BIGNUMBER_H #define BIGNUMBER_H #include <iostream> #include <string> class BigNumber { public: BigNumber(); BigNumber(std::string s_16); BigNumber(const BigNumber &number); /************************************************************************/ /* 改变数值的操作 */ /************************************************************************/ void setMaxValue(); void setMinValue(); BigNumber& operator++();//前缀重载 const BigNumber operator++(int);//后缀重载 BigNumber& operator--();//前缀重载 const BigNumber operator--(int);//后缀重载 const BigNumber& operator=(const BigNumber &number); const BigNumber& operator+=(const BigNumber &number); const BigNumber& operator-=(const BigNumber &number); /************************************************************************/ /* 基本运算操作 */ /************************************************************************/ const BigNumber operator+(const BigNumber &number); const BigNumber operator-(const BigNumber &number); const BigNumber operator*(const BigNumber &number);//————————未完成 const BigNumber operator/(const BigNumber &number);//————————未完成 /************************************************************************/ /* 大小比较操作 */ /************************************************************************/ bool operator>(const BigNumber &number); bool operator<(const BigNumber &number); bool operator==(const BigNumber &number); bool operator<=(const BigNumber &number); bool operator>=(const BigNumber &number); /************************************************************************/ /* 输出操作 */ /************************************************************************/ friend std::ostream& operator<<(std::ostream &os, BigNumber &number); friend std::istream& operator>>(std::istream &is, BigNumber &number); const static unsigned int MaxValue = 0xFFFFFFFF;//一个无符号整数的最大值 const static unsigned int MinValue = 0x00000000;//一个无符号整数的最小值 const static unsigned int Size = 100;//存储区大小 private: unsigned int data[Size];//存储区 void _add(unsigned int data[], unsigned int posion);//进位操作 void _sub(unsigned int data[], unsigned int posion);//借位操作 unsigned char toBit4(char c);//字符转数值 char fromBit4(unsigned char c);//数值转字符 void set_Bit16(std::string s_16); std::string get_Bit16(); }; #endif
BigNumber.cpp
#include "BigNumber.h" /************************************************************************/ /* 默认构造函数,初始数值为0 */ /************************************************************************/ BigNumber::BigNumber() { setMinValue(); } /************************************************************************/ /* 以一个16进制表示的字符串初始化大数 */ /************************************************************************/ BigNumber::BigNumber(std::string s_16) { this->set_Bit16(s_16); } /************************************************************************/ /* 拷贝构造函数 */ /************************************************************************/ BigNumber::BigNumber(const BigNumber &number) { for (unsigned int index = 0; index < BigNumber::Size; index++) { this->data[index] = number.data[index]; } } /************************************************************************/ /* 进位操作实际上是一个自加的过程,如果低位的数值自加后会溢出,则将 */ /* 高一位的数也自加,否则就直接将当前数值自加后退出 */ /************************************************************************/ void BigNumber::_add(unsigned int data[], unsigned int posion) { if (this->data[posion] == 0xFFFFFFFF)//如果当前位的值为最大值 { if (posion == Size - 1)//如果到达最高位,则直接进行自加,不再进位 { this->data[posion]++; return; } _add(data, posion + 1);//通过将高位自加来表示进位 this->data[posion]++; } else//若不是最大值则进行自加 { this->data[posion]++; } } /************************************************************************/ /* 借位操作实际上是一个自减的过程,如果低位的数值自减后会溢出,则将 */ /* 高一位的数也自减,否则就直接将当前数值自减后退出 */ /************************************************************************/ void BigNumber::_sub(unsigned int data[], unsigned int posion) { if (this->data[posion] == 0x00000000)//如果当前位的值为最小值 { if (posion == BigNumber::Size - 1)//如果到达最高位,则直接进行自减,不再借位 { this->data[posion]--; return; } _sub(data, posion + 1);//通过将高位自减来表示借位 this->data[posion]--; } else//若不是最小值则进行自减 { this->data[posion]--; } } /************************************************************************/ /* 将一个16进制表示的字符转为数值 */ /************************************************************************/ unsigned char BigNumber::toBit4(char c) { if (c <= '9'&&c >= '0') { return c - '0'; } else if (c <= 'F'&&c >= 'A') { return c - 'A' + 10; } else if (c <= 'f'&&c >= 'a') { return c - 'a' + 10; } else { return 0xf0; } } /************************************************************************/ /* 将一个0~15之内的数值转为16进制表示的字符 */ /************************************************************************/ char BigNumber::fromBit4(unsigned char n) { if (n <= 9 && n >= 0) { return n + '0'; } if (n <= 15 && n >= 10) { return n + 'A' - 10; } return '\0'; } /************************************************************************/ /* 将数值转为一个16进制表示的字符串,并返回该字符串 */ /************************************************************************/ std::string BigNumber::get_Bit16() { unsigned int index1 = BigNumber::Size - 1; while (this->data[index1] == 0) //指向最高有效位 { if (index1 == 0) { break; } index1--; } std::string s_16; for (unsigned int i = index1 + 1; i > 0; i--) { unsigned char bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0; unsigned int temp = this->data[i - 1];//取出一个32位 /* 从高到低得到每一个4bit */ bit7 = (temp >> 28) & 0xf; bit6 = (temp >> 24) & 0xf; bit5 = (temp >> 20) & 0xf; bit4 = (temp >> 16) & 0xf; bit3 = (temp >> 12) & 0xf; bit2 = (temp >> 8) & 0xf; bit1 = (temp >> 4) & 0xf; bit0 = temp & 0xf; s_16 += fromBit4(bit7); s_16 += fromBit4(bit6); s_16 += fromBit4(bit5); s_16 += fromBit4(bit4); s_16 += fromBit4(bit3); s_16 += fromBit4(bit2); s_16 += fromBit4(bit1); s_16 += fromBit4(bit0); } return s_16; } /************************************************************************/ /* 接受一个16进制数的字符串,将其存入转为BigNumber */ /************************************************************************/ void BigNumber::set_Bit16(std::string s_16) { this->setMinValue();//置零 unsigned int size = s_16.size();//补位,不够32位则高位补零 if (size % 8 == 7) { s_16 = "0" + s_16; } else if (size % 8 == 6) { s_16 = "00" + s_16; } else if (size % 8 == 5) { s_16 = "000" + s_16; } else if (size % 8 == 4) { s_16 = "0000" + s_16; } else if (size % 8 == 3) { s_16 = "00000" + s_16; } else if (size % 8 == 2) { s_16 = "000000" + s_16; } else if (size % 8 == 1) { s_16 = "0000000" + s_16; } /************************************************************************/ /* 一次取8个字符,将其转为32位无符号整数存入 */ /************************************************************************/ for (unsigned int i = 0; i < s_16.size() / 8; ++i) { std::string c4 = s_16.substr(8 * i, 8 * i + 8); unsigned int bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0; bit7 = toBit4(c4[0]); bit6 = toBit4(c4[1]); bit5 = toBit4(c4[2]); bit4 = toBit4(c4[3]); bit3 = toBit4(c4[4]); bit2 = toBit4(c4[5]); bit1 = toBit4(c4[6]); bit0 = toBit4(c4[7]); this->data[s_16.size() / 8 - i - 1] |= bit7; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit6; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit5; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit4; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit3; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit2; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit1; this->data[s_16.size() / 8 - i - 1] <<= 4; this->data[s_16.size() / 8 - i - 1] |= bit0; } } /************************************************************************/ /* 设置数值为最小值 */ /************************************************************************/ void BigNumber::setMaxValue() { for (unsigned int index = 0; index < BigNumber::Size; index++) { data[index] = 0xFFFFFFFF; } } /************************************************************************/ /* 设置数值为最大值 */ /************************************************************************/ void BigNumber::setMinValue() { for (unsigned int index = 0; index < BigNumber::Size; index++) { data[index] = 0x00000000; } } const BigNumber& BigNumber::operator=(const BigNumber &number) { for (unsigned int index = 0; index < BigNumber::Size; index++) { this->data[index] = number.data[index]; } return *this; } const BigNumber& BigNumber::operator+=(const BigNumber &number) { *this = *this + number; return *this; } const BigNumber& BigNumber::operator-=(const BigNumber &number) { *this = *this - number; return *this; } BigNumber& BigNumber::operator++()//前缀重载,返回自加之后的值 { _add(this->data, 0); return *this; } const BigNumber BigNumber::operator++(int)//后缀重载,返回自加之前的值 { BigNumber n = *this; _add(this->data, 0); return n; } BigNumber& BigNumber::operator--()//前缀重载,返回自减之后的值 { _sub(this->data, 0); return *this; } const BigNumber BigNumber::operator--(int)//后缀重载,返回自减之前的值 { BigNumber n = *this; _sub(this->data, 0); return n; } /******************************************************************************/ /* 加法操作并不会改变两个操作数本身的值,所以这里保存第一个加数的值到变量n */ /* 中,并将最终的和保存到变量n中,返回变量n的值 */ /******************************************************************************/ const BigNumber BigNumber::operator+(const BigNumber &number) { BigNumber n = *this; for (unsigned int index = 0; index < BigNumber::Size - 1; ++index) { if (BigNumber::MaxValue - this->data[index] < number.data[index])//如果需要进位则执行进位操作 { n._add(n.data, index + 1); } n.data[index] = n.data[index] + number.data[index];//执行加法 } n.data[BigNumber::Size - 1] = n.data[BigNumber::Size - 1] + number.data[BigNumber::Size - 1];//最高位不用进行进位 return n; } /******************************************************************************/ /* 减法操作并不会改变两个操作数本身的值,所以这里保存被减数的值到 变量n中 */ /* 并将最终的差保存到变量n中,返回变量n的值 */ /******************************************************************************/ const BigNumber BigNumber::operator - (const BigNumber &number) { BigNumber n = *this; for (unsigned int index = 0; index < BigNumber::Size - 1; ++index) { if (n.data[index] < number.data[index])//如果不够减,就执行借位操作 { n._sub(n.data, index + 1);//借位 } n.data[index] = n.data[index] - number.data[index];//执行减法 } n.data[BigNumber::Size - 1] = n.data[BigNumber::Size - 1] - number.data[BigNumber::Size - 1];//最高位不需要借位 return n; } /************************************************************************/ /* 比较大小操作 */ /************************************************************************/ bool BigNumber::operator>(const BigNumber &number) { unsigned int index1 = BigNumber::Size - 1;//分别指向最大下标 unsigned int index2 = BigNumber::Size - 1; while (this->data[index1] == 0) //指向最高有效位 { if (index1 == 0) { break; } index1--; } while (number.data[index2] == 0) //指向最高有效位 { if (index2 == 0) { break; } index2--; } if (index1 > index2) { return true; } else if (index1 <index2) { return false; } else//当最高有效位的存储区下标相同时,比较存储区内的数值 { if (this->data[index1] > number.data[index2]) { return true; } else { return false; } } } bool BigNumber::operator<(const BigNumber &number) { unsigned int index1 = BigNumber::Size - 1;//分别指向最大下标 unsigned int index2 = BigNumber::Size - 1; while (this->data[index1] == 0) //指向最高有效位 { if (index1 == 0) { break; } index1--; } while (number.data[index2] == 0) //指向最高有效位 { if (index2 == 0) { break; } index2--; } if (index1 < index2) { return true; } else if (index1 > index2) { return false; } else//当最高有效位的存储区下标相同时,比较存储区内的数值 { if (this->data[index1] < number.data[index2]) { return true; } else { return false; } } } bool BigNumber::operator == (const BigNumber &number) { for (unsigned int index = 0; index < BigNumber::Size; index++) { if (this->data[index] != number.data[index])//只要遇到存储的数值不一样就返回false { return false; } } return true; } bool BigNumber::operator <= (const BigNumber &number) { if (*this < number || *this == number) { return true; } return false; } bool BigNumber::operator >= (const BigNumber &number) { if (*this > number || *this == number) { return true; } return false; } /************************************************************************/ /* 重载输出操作,输出一个16进制的字符串,以0x开头 */ /************************************************************************/ //std::ostream& operator<<(std::ostream &os, BigNumber &number) //{ // std::string s_16; // s_16 = number.get_Bit16(); // os << "0x" << s_16; // return os; //} std::ostream& operator<<(std::ostream &os, BigNumber &number) { std::string s_16; s_16 = number.get_Bit16(); os << s_16; return os; } /************************************************************************/ /* 重载输入操作,接收一个16进制的字符串,不需要0x开头 */ /************************************************************************/ std::istream& operator>>(std::istream &is, BigNumber &number) { std::string s_16; is >> s_16; number.set_Bit16(s_16); return is; }
main.cpp
#include "BigNumber.h" #include <string> using namespace std; int main() { string Num0("2000000000000000000000000000000000000000100");/*1234567891011121314151617181920*/ string Num1("1000000000000000000000000000000000000000200");/*21222324252627282930313233343536*/ BigNumber MyBigNum0(Num0); BigNumber MyBigNum1(Num1); BigNumber MyBigNum2; MyBigNum2=MyBigNum0 + MyBigNum1; cout << MyBigNum0 << endl; cout << MyBigNum1 << endl; cout << MyBigNum2 << endl; return 0; }