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); } */ }
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); } }
void BigNumber::Add(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(); if (iNumber != aX.iNumber && iNumber != aY.iNumber && aX.iNumber->iExp == aY.iNumber->iExp && aX.iNumber->iTensExp == aY.iNumber->iTensExp) { ::Add(*iNumber, *aX.iNumber, *aY.iNumber); } else { ANumber a1(*aX.iNumber ); ANumber a2(*aY.iNumber ); ::Add(*iNumber, a1, a2); } iNumber->SetPrecision(aPrecision); /* */ }
void BigNumber::SetTo(const BigNumber& aOther) { iPrecision = aOther.GetPrecision(); if (!iNumber) { iNumber = new ANumber(*aOther.iNumber); } else { iNumber->CopyFrom(*aOther.iNumber); } SetIsInteger(aOther.IsInt()); }
BigNumber::BigNumber(const BigNumber& aOther) : iReferenceCount(),iPrecision(aOther.GetPrecision()),iType(KInt),iNumber(nullptr) { iNumber = new ANumber(*aOther.iNumber); SetIsInteger(aOther.IsInt()); }