⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bigint.cpp

📁 C++&datastructure书籍源码,以前外教提供现在与大家共享
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <iostream>using namespace std;#include <stdlib.h>#include <ctype.h>#include <limits.h>#include "bigint.h"#include "tvector.h"// #define DEBUGconst int BASE = 10;// author: Owen Astrachan//// BigInts are implemented using a Vector<char> to store// the digits of a BigInt// Currently a number like 5,879 is stored as the vector {9,7,8,5}// i.e., the least significant digit is the first digit in the vector;// for example, GetDigit(0) returns 9 and getDigit(3) returns 5.// All operations on digits should be done using private// helper functions://// int  GetDigit(k)        -- return k-th digit// void ChangeDigit(k,val) -- set k-th digit to val// void AddSigDigit(val)   -- add new most significant digit val//// by performing all ops in terms of these private functions we// make implementation changes simpler//// I/O operations are facilitated by the ToString() member function// which converts a BigInt to its string (ASCII) representationBigInt::BigInt()// postcodition: bigint initialized to 0   : mySign(positive),     myDigits(1,'0'),     myNumDigits(1){	// all fields initialized in initializer list#ifdef DEBUG            cout << "default constructor called" << endl;#endif	}BigInt::BigInt(const BigInt & rhs)    : mySign(rhs.mySign),      myDigits(rhs.myDigits),      myNumDigits(rhs.myNumDigits){#ifdef DEBUG        cout << "copy constructor called with " << rhs << endl;#endif    }BigInt::~BigInt(){#ifdef DEBUG    cout << "destructor called for " << *this << endl;#endif}const BigInt & BigInt::operator = (const BigInt & rhs){#ifdef DEBUG	cout << "assignment operator called with " << rhs << endl;#endif	mySign = rhs.mySign;	myNumDigits = rhs.myNumDigits;	myDigits = rhs.myDigits;	return *this;}BigInt::BigInt(int num)// postcondition: bigint initialized to num   : mySign(positive),     myDigits(1,'0'),     myNumDigits(0){    // check if num is negative, change state and num accordingly   unsigned int copy;   // use this to avoid problems with INT_MIN != -INT_MAX #ifdef DEBUG        cout << "int constructor called  " << num << endl;#endif       if (num < 0)    {   mySign = negative;        if (num == INT_MIN)        {   copy = unsigned(INT_MAX) + 1;        }        else        {   copy = -1 * num;        }    }    else    {   copy = num;    }    // handle least-significant digit of num (handles num == 0)    AddSigDigit(copy % BASE);    copy = copy / BASE;    // handle remaining digits of num    while (copy != 0)    {   AddSigDigit(copy % BASE);        copy = copy / BASE;    }}BigInt::BigInt(const string & s)// precondition: s consists of digits only, optionally preceded by + or -// postcondition: bigint initialized to integer represented by s//                if s is not a well-formed BigInt (e.g., contains non-digit//                characters) then an error message is printed and abort called  : mySign(positive),    myDigits(s.length(),'0'),    myNumDigits(0){    int k;    int limit = 0;#ifdef DEBUG        cout << "string constructor called s = " << s << endl;#endif       if (s.length() == 0)    {   myDigits.resize(1);        AddSigDigit(0);        return;    }    if (s[0] == '-')    {   mySign = negative;        limit = 1;    }    if (s[0] == '+')    {   limit = 1;    }    // start at least significant digit    for(k=s.length() - 1; k >= limit; k--)    {   if (! isdigit(s[k]))        {   cerr << "badly formed BigInt value = " << s << endl;            abort();        }        AddSigDigit(s[k]-'0');    }    Normalize();}const BigInt & BigInt::operator -=(const BigInt & rhs)// postcondition: returns value of bigint - rhs after subtraction{    int diff;    int borrow = 0;    int k;    int len = NumDigits();    if (this == &rhs)         // subtracting self?    {        *this = 0;        return *this;    }    // signs opposite? then lhs - (-rhs) = lhs + rhs    if (IsNegative() != rhs.IsNegative())    {        *this +=(-1 * rhs);        return *this;    }    // signs are the same, check which number is larger    // and switch to get larger number "on top" if necessary    // since sign can change when subtracting    // examples: 7 - 3 no sign change,     3 - 7 sign changes    //          -7 - (-3) no sign change, -3 -(-7) sign changes    if (IsPositive() && (*this) < rhs ||        IsNegative() && (*this) > rhs)    {        *this = rhs - *this;        if (IsPositive()) mySign = negative;        else              mySign = positive;   // toggle sign        return *this;    }    // same sign and larger number on top    for(k=0; k < len; k++)    {        diff = GetDigit(k) - rhs.GetDigit(k) - borrow;        borrow = 0;        if (diff < 0)        {   diff += BASE;            borrow = 1;        }        ChangeDigit(k,diff);    }    Normalize();    return *this;}const BigInt & BigInt::operator +=(const BigInt & rhs)// postcondition: returns value of bigint + rhs after addition{    int sum;    int carry = 0;    int k;    int len = NumDigits();         // length of larger addend    if (this == &rhs)              // to add self, multiply by 2    {      *this *= 2;      return *this;    }    if (rhs == 0)                   // zero is special case    {   return *this;    }    if (IsPositive() != rhs.IsPositive())    // signs not the same, subtract    {        *this -= (-1 * rhs);        return *this;    }    // process both numbers until one is exhausted    if (len < rhs.NumDigits())    {        len = rhs.NumDigits();    }    for(k=0; k < len; k++)    {        sum = GetDigit(k) + rhs.GetDigit(k) + carry;        carry = sum / BASE;        sum = sum % BASE;        if (k < myNumDigits)        {            ChangeDigit(k,sum);        }        else        {            AddSigDigit(sum);        }    }    if (carry != 0)    {        AddSigDigit(carry);    }    return *this;}BigInt operator +(const BigInt & lhs, const BigInt & rhs)// postcondition: returns a bigint whose value is lhs + rhs{    BigInt result(lhs);    result += rhs;    return result;}BigInt operator -(const BigInt & lhs, const BigInt & rhs)// postcondition: returns a bigint whose value is lhs + rhs{    BigInt result(lhs);    result -= rhs;    return result;}string BigInt::ToString() const// postcondition: returns string equivalent of BigInt{    int k;    int len = NumDigits();    string s = "";    if (IsNegative())    {        s = '-';    }    for(k=len-1; k >= 0; k--)    {        s += char('0'+GetDigit(k));    }    return s;}int BigInt::ToInt() const// precondition: INT_MIN <= self <= INT_MAX// postcondition: returns int equivalent of self{    int result = 0;    int k;    if (INT_MAX < *this) return INT_MAX;    if (*this < INT_MIN) return INT_MIN;    for(k=NumDigits()-1; k >= 0; k--)    {        result = result * BASE + GetDigit(k);    }    if (IsNegative())    {        result *= -1;    }    return result;}double BigInt::ToDouble() const// precondition: DBL_MIN <= self <= DLB_MAX// postcondition: returns double equivalent of self{    double result = 0.0;    int k;    for(k=NumDigits()-1; k >= 0; k--)    {        result = result * BASE + GetDigit(k);    }    if (IsNegative())    {        result *= -1;    }    return result;}ostream & operator <<(ostream & out, const BigInt & big)// postcondition: big inserted onto stream out{    out << big.ToString();    return out;}istream & operator >> (istream & in, BigInt & big)// postcondition: big extracted from in, must be whitespace delimited{    string s;    in >> s;    big = BigInt(s);    return in;}bool operator == (const BigInt & lhs, const BigInt & rhs)// postcondition: returns true if lhs == rhs, else returns false{    return lhs.Equal(rhs);}bool BigInt::Equal(const BigInt & rhs) const// postcondition: returns true if self == rhs, else returns false{    if (NumDigits() != rhs.NumDigits() || IsNegative() != rhs.IsNegative())    {        return false;    }    // assert: same sign, same number of digits;    int k;    int len = NumDigits();    for(k=0; k < len; k++)    {        if (GetDigit(k) != rhs.GetDigit(k)) return false;    }    return true;}bool operator != (const BigInt & lhs, const BigInt & rhs)// postcondition: returns true if lhs != rhs, else returns false{    return ! (lhs == rhs);}bool operator < (const BigInt & lhs, const BigInt & rhs)// postcondition: return true if lhs < rhs, else returns false{    return lhs.LessThan(rhs);}bool BigInt::LessThan(const BigInt & rhs) const// postcondition: return true if self < rhs, else returns false{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -