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

📄 bigint.cpp

📁 C++&datastructure书籍源码,以前外教提供现在与大家共享
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // if signs aren't equal, self < rhs only if self is negative    if (IsNegative() != rhs.IsNegative())    {        return IsNegative();    }    // if # digits aren't the same must check # digits and sign    if (NumDigits() != rhs.NumDigits())    {        return (NumDigits() < rhs.NumDigits() && IsPositive()) ||               (NumDigits() > rhs.NumDigits() && IsNegative());    }    // assert: # digits same, signs the same    int k;    int len = NumDigits();    for(k=len-1; k >= 0; k--)    {        if (GetDigit(k) < rhs.GetDigit(k)) return IsPositive();        if (GetDigit(k) > rhs.GetDigit(k)) return IsNegative();    }    return false;      // self == rhs}bool operator > (const BigInt & lhs, const BigInt & rhs)// postcondition: return true if lhs > rhs, else returns false{    return rhs < lhs;}bool operator <= (const BigInt & lhs, const BigInt & rhs)// postcondition: return true if lhs <= rhs, else returns false{    return lhs == rhs || lhs < rhs;}bool operator >= (const BigInt & lhs, const BigInt & rhs)// postcondition: return true if lhs >= rhs, else returns false{    return lhs == rhs || lhs > rhs;}void BigInt::Normalize()// postcondition: all leading zeros removed{    int k;    int len = NumDigits();    for(k=len-1; k >= 0; k--)        // find a non-zero digit    {        if (GetDigit(k) != 0) break;        myNumDigits--;               // "chop" off zeros    }    if (k < 0)    // all zeros    {        myNumDigits = 1;        mySign = positive;    }}const BigInt & BigInt::operator *=(int num)// postcondition: returns num * value of BigInt after multiplication{    int carry = 0;    int product;               // product of num and one digit + carry    int k;    int len = NumDigits();    if (0 == num)              // treat zero as special case and stop    {        *this = 0;        return *this;    }    if (BASE < num|| num < 0)        // handle pre-condition failure    {        *this *= BigInt(num);        return *this;    }    if (1 == num)              // treat one as special case, no work    {        return *this;    }    for(k=0; k < len; k++)     // once for each digit    {        product = num * GetDigit(k) + carry;        carry = product/BASE;        ChangeDigit(k,product % BASE);    }    while (carry != 0)         // carry all digits    {        AddSigDigit(carry % BASE);        carry /= BASE;    }    return *this;}BigInt operator *(const BigInt & a, int num)// postcondition: returns a * num{    BigInt result(a);    result *= num;    return result;}BigInt operator *(int num, const BigInt & a)// postcondition: returns num * a{    BigInt result(a);    result *= num;    return result;}const BigInt & BigInt::operator *=(const BigInt & rhs)// postcondition: returns value of bigint * rhs after multiplication{    // uses standard "grade school method" for multiplying   if (IsNegative() != rhs.IsNegative())   {      mySign = negative;   }   else   {      mySign = positive;   }    BigInt self(*this);                        // copy of self    BigInt sum(0);                             // to accumulate sum    int k;    int len = rhs.NumDigits();                 // # digits in multiplier    for(k=0; k < len; k++)    {       sum += self * rhs.GetDigit(k);          // k-th digit * self       self *= BASE;                           // add a zero    }    *this = sum;    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;}int BigInt::NumDigits() const// postcondition: returns # digits in BigInt{    return myNumDigits;}int BigInt::GetDigit(int k) const// precondition: 0 <= k < NumDigits()// postcondition: returns k-th digit//                (0 if precondition is false)//                Note: 0th digit is least significant digit{    if (0 <= k && k < NumDigits())    {        return myDigits[k] - '0';    }    return 0;}void BigInt::ChangeDigit(int k, int value)// precondition: 0 <= k < NumDigits()// postcondition: k-th digit changed to value//                Note: 0th digit is least significant digit{    if (0 <= k && k < NumDigits())    {        myDigits[k] = char('0' + value);    }    else    {        cerr << "error changeDigit " << k << " " << myNumDigits << endl;    }}void BigInt::AddSigDigit(int value)// postcondition: value added to BigInt as most significant digit//                Note: 0th digit is least significant digit{    if (myNumDigits >= myDigits.length())    {        myDigits.resize(myDigits.length() * 2);    }    myDigits[myNumDigits] = char('0' + value);    myNumDigits++;}bool BigInt::IsNegative() const// postcondition: returns true iff BigInt is negative{    return mySign == negative;}bool BigInt::IsPositive() const// postcondition: returns true iff BigInt is positive{   return mySign == positive;}void BigInt::DivideHelp(const BigInt & lhs, const BigInt & rhs,                        BigInt & quotient, BigInt & remainder)// postcondition: quotient = lhs / rhs//                remainder = lhs % rhs     {    if (lhs < rhs)             // integer division yields 0    {                          // so avoid work and return        quotient = 0;                remainder = lhs;        return;    }    else if (lhs == rhs)       // again, avoid work in special case    {        quotient = 1;        remainder = 0;        return;    }        BigInt dividend(lhs);      // make copies because of const-ness    BigInt divisor(rhs);    quotient = remainder = 0;    int k,trial;    int zeroCount = 0;    // pad divisor with zeros until # of digits = dividend        while (divisor.NumDigits() < dividend.NumDigits())    {        divisor *= BASE;        zeroCount++;    }    // if we added one too many zeros chop one off        if (divisor > dividend)    {        divisor /= BASE;        zeroCount--;    }    // algorithm: make a guess for how many times dividend part    // goes into divisor, adjust the guess, subtract out and repeat        int divisorSig = divisor.GetDigit(divisor.NumDigits()-1);    int dividendSig;    BigInt hold;        for(k=0; k <= zeroCount; k++)    {        dividendSig = dividend.GetDigit(dividend.NumDigits()-1);        trial =            (dividendSig*BASE + dividend.GetDigit(dividend.NumDigits()-2))            /divisorSig;                if (BASE <= trial)   // stay within base        {            trial = BASE-1;        }        while ((hold = divisor * trial) > dividend)        {            trial--;        }        // accumulate quotient by adding digits to quotient        // and chopping them off of divisor after adjusting dividend                quotient *= BASE;        quotient += trial;        dividend -= hold;        divisor /= BASE;               divisorSig = divisor.GetDigit(divisor.NumDigits()-1);            }    remainder = dividend;}const BigInt & BigInt::operator /=(const BigInt & rhs)// postcondition: return BigInt / rhs after modification{    BigInt quotient,remainder;    bool resultNegative = (IsNegative() != rhs.IsNegative());    mySign = positive;      // force myself positive        // DivideHelp does all the work        if (rhs.IsNegative())    {        DivideHelp(*this,-1*rhs,quotient,remainder);    }    else    {        DivideHelp(*this,rhs,quotient,remainder);           }    *this = quotient;    mySign = resultNegative ? negative : positive;    Normalize();    return *this;}BigInt operator / (const BigInt & lhs, const BigInt & rhs)// postcondition: return lhs / rhs{    BigInt result(lhs);    result /= rhs;    return result;}const BigInt & BigInt::operator /=(int num)// precondition: 0 < num < BASE     // postcondition: returns BigInt/num after modification{    int carry = 0;    int quotient;    int k;    int len = NumDigits();    if (num > BASE)     // check precondition    {        return operator /= (BigInt(num));    }    if (0 == num)       // handle division by zero     {        cerr << "division by zero error" << endl;		abort();    }    else    {        for(k=len-1; k >= 0; k--)  // once for each digit        {            quotient = (BASE*carry + GetDigit(k));            carry = quotient % num;            ChangeDigit(k, quotient / num);        }    }    Normalize();    return *this;}BigInt operator /(const BigInt & a, int num)// postcondition: returns a / num     {    BigInt result(a);    result /= num;    return result;}BigInt operator %(const BigInt & lhs, const BigInt & rhs)// postcondition: returns lhs % rhs     {    BigInt result(lhs);    result %= rhs;    return result;}const BigInt & BigInt::operator %=(const BigInt & rhs)// postcondition: returns BigInt % rhs after modification     {    BigInt quotient,remainder;    bool resultNegative = IsNegative();        // DivideHelp does all the work        if (rhs.IsNegative())    {        DivideHelp(*this,-1 * rhs,quotient,remainder);    }    else    {        DivideHelp(*this,rhs,quotient,remainder);           }    *this = remainder;    mySign = resultNegative ? negative : positive;       return *this;}

⌨️ 快捷键说明

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