65.9K
CodeProject 正在变化。 阅读更多。
Home

用于处理大整数的类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (12投票s)

2001年6月16日

Ms-PL
viewsIcon

128829

downloadIcon

2367

介绍一个 C++ 类,使用 STL 向量容器进行大整数运算的算法。

类的完整代码包含在文章关联的项目LargeNumber.zip中。 这里我只展示类的接口。

class CLargeNumber
{
public:
  //Default Constructor
  CLargeNumber() : m_cSign(1) { m_oNumber.push_back(0); }

  //Copy Constructor - Default OK
  //CLargeNumber(CLargeNumber const& rcoLargeNumber) : 
  //	m_cSign(rcoLargeNumber.m_cSign), m_oNumber(rcoLargeNumber.m_oNumber) {}

  //Constructor From a Number
  CLargeNumber(int iNumber);
  //Constructor From a String
  CLargeNumber(string const& rostrNumber);
  //Constructor From Members
  CLargeNumber(char cSign, vector<char> const& rcoNumber) : 
  	m_cSign(cSign), m_oNumber(rcoNumber) {}

  //Assignment Operator - Default OK
  //CLargeNumber& operator=(CLargeNumber const& roLN);

protected:
  //Auxiliary class Functions:
  //Build from unsigned long
  static void Build(unsigned uN, vector<char>& rvN);
  //Build from string
  static void Build(string const& rostrNumber, vector<char>& rvN);
  //Cleaning
  static void Clean(vector<char>& rvN);
  //Comparison Function
  static int Compare(vector<char> const& rcvN1, vector<char> const& rcvN2);
  //Addition
  static void Add(vector<char> const& rcvN1, vector<char> const& rcvN2, 
vector<char>& rvNRes); //Subtraction static void Subtract(vector<char> const& rcvN1, vector<char> const& rcvN2,
vector<char>& rvNRes); //Product with one digit static void Multiply(vector<char> const& rcvN, char c, vector<char>& rvNRes); //Shift Left static void ShiftLeft(vector<char>& rvN, int iLeft); //Multiplication static void Multiply(vector<char> const& rcvN1, vector<char> const& rcvN2,
vector<char>& rvNRes); //Get the Position of the most significant Digit static int Position(vector<char> const& rcvN); //Compute a Power of 10 static void Pow10(unsigned uPow, vector<char>& rvNRes); //Division static void Divide(vector<char> const& rcvN1, vector<char> const& rcvN2, vector<char>& rvQ, vector<char>& rvR); public: //Transform to a string string ToString() const; //Operators //Equality Operator bool operator==(CLargeNumber const& roLN); //Inequality Operator bool operator!=(CLargeNumber const& roLN); CLargeNumber& operator-(); bool operator<(CLargeNumber const& roLN) const; bool operator>(CLargeNumber const& roLN) const; bool operator<=(CLargeNumber const& roLN) const; bool operator>=(CLargeNumber const& roLN) const; CLargeNumber operator+(CLargeNumber const& roLN) const; CLargeNumber operator-(CLargeNumber const& roLN) const; CLargeNumber operator*(CLargeNumber const& roLN) const; CLargeNumber operator/(CLargeNumber const& roLN) const; CLargeNumber operator%(CLargeNumber const& roLN) const; CLargeNumber& operator+=(CLargeNumber const& roLN); CLargeNumber& operator-=(CLargeNumber const& roLN); CLargeNumber& operator*=(CLargeNumber const& roLN); CLargeNumber& operator/=(CLargeNumber const& roLN); CLargeNumber& operator%=(CLargeNumber const& roLN); //Convertion operator operator int() const; //Square Root CLargeNumber SquareRoot() const; private: //-1 - Negative, +1 - Positive or zero char m_cSign; vector<char> m_oNumber; };

我使用 STL vector<char> 容器 m_oNumber 来存储数字的十进制数字。 数字按从低到高的顺序存储。 数字的符号存储在 char m_cSign 字段中。 正大数的运算在一些辅助静态函数中实现。 我更喜欢使用静态函数,因为这些辅助函数不依赖于类的字段成员。 带有符号的大数的运算使用广泛的运算符重载实现,并在内部使用辅助静态函数。 一些使用该类的示例

加法

CLargeNumber oLN1("1111111434311111");
CLargeNumber oLN2("2222222233422222");
cout << (oLN1+oLN2).ToString() << endl;

减法

CLargeNumber oLN1("12323523664");
CLargeNumber oLN2("325454361234");
cout << (oLN1-oLN2).ToString() << endl;

乘法

CLargeNumber oLN1("123456834333466");
CLargeNumber oLN2(1000);
cout << (oLN1*oLN2).ToString() << endl;

除法

这将为除以0抛出异常

try
{
  CLargeNumber oLN1("1234655123667");
  CLargeNumber oLN2(500);
  cout << (oLN1/oLN2).ToString() << endl;
  cout << (oLN1%oLN2).ToString() << endl;
}
catch(exception& roEx)
{
  cout << roEx.what() << endl;
}

平方根

这将为负数抛出异常

try
{
  CLargeNumber oLN1("1000000000000000000");
  cout << oLN1.SquareRoot().ToString() << endl;
}
catch(exception& roEx)
{
  cout << roEx.what() << endl;
}

阶乘

在测试程序中,我还实现了一个用于阶乘计算的小函数

CLargeNumber Factorial(int iNumber)
{
  CLargeNumber oLN("1");
  if(iNumber > 1)
  {
    for(int i=2; i<=iNumber; i++)
      oLN *= i;
  }
  return oLN;
}

示例

作为一个例子,我给出了100!的158位数字。

9332621544394415268169923885626670049071596826438162146859296389521759999322991
5608941463976156518286253697920827223758251185210916864000000000000000000000000

希望您能玩得开心!

© . All rights reserved.