void BigNumber::Multiply(const BigNumber& aX, const BigNumber& aY, int aPrecision) { SetIsInteger(aX.IsInt() && aY.IsInt()); if (aPrecision<aX.GetPrecision()) aPrecision=aX.GetPrecision(); if (aPrecision<aY.GetPrecision()) aPrecision=aY.GetPrecision(); iNumber->ChangePrecision(bits_to_digits(aPrecision,10)); // if (iNumber == aX.iNumber || iNumber == aY.iNumber) { ANumber a1(*aX.iNumber); ANumber a2(*aY.iNumber); :: Multiply(*iNumber,a1,a2); } /*TODO I don't like that multiply is destructive, but alas... x=pi;x*0.5 demonstrates this. FIXME else { :: Multiply(*iNumber,*aX.iNumber,*aY.iNumber); } */ }
/// return a string representation in decimal LispString * LispNumber::String() { if (!iString) { assert(iNumber.ptr()); // either the string is null or the number but not both LispString *str = NEW LispString; // export the current number to string and store it as LispNumber::iString iNumber->ToString(*str, bits_to_digits(std::max(1,iNumber->GetPrecision()),BASE10), BASE10); iString = str; } return iString; }
void BigNumber::Divide(const BigNumber& aX, const BigNumber& aY, int aPrecision) { /* iPrecision = DividePrecision(aX, aY, aPrecision); int digitPrecision = bits_to_digits(iPrecision,10); iNumber->iPrecision = digitPrecision; */ /* */ if (aPrecision<aX.GetPrecision()) aPrecision=aX.GetPrecision(); if (aPrecision<aY.GetPrecision()) aPrecision=aY.GetPrecision(); int digitPrecision = bits_to_digits(aPrecision,10); iPrecision = aPrecision; iNumber->iPrecision = digitPrecision; /* */ ANumber a1(*aX.iNumber); // a1.CopyFrom(*aX.iNumber); ANumber a2(*aY.iNumber); // a2.CopyFrom(*aY.iNumber); ANumber remainder(digitPrecision); if (a2.IsZero()) throw LispErrInvalidArg(); if (aX.IsInt() && aY.IsInt()) { if (a1.iExp != 0 || a2.iExp != 0) throw LispErrNotInteger(); SetIsInteger(true); ::IntegerDivide(*iNumber, remainder, a1, a2); } else { SetIsInteger(false); ::Divide(*iNumber,remainder,a1,a2); } }
BigNumber::BigNumber(int aPrecision) : iReferenceCount(),iPrecision(aPrecision),iType(KInt),iNumber(nullptr) { iNumber = new ANumber(bits_to_digits(aPrecision,10)); SetIsInteger(true); }