X-Git-Url: https://mattmccutchen.net/bigint/bigint.git/blobdiff_plain/83a639e66e094c683b48215a895f6d35e9d60d32..refs/heads/no-explicit-template-args:/BigInteger.cc diff --git a/BigInteger.cc b/BigInteger.cc index 56f30ab..dac50d9 100644 --- a/BigInteger.cc +++ b/BigInteger.cc @@ -13,11 +13,18 @@ void BigInteger::operator =(const BigInteger &x) { BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) { switch (s) { case zero: + if (!mag.isZero()) + throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude"; + sign = zero; + break; case positive: case negative: + // If the magnitude is zero, force the sign to zero. sign = mag.isZero() ? zero : s; break; default: + /* g++ seems to be optimizing out this case on the assumption + * that the sign is a valid member of the enumeration. Oh well. */ throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign"; } } @@ -25,12 +32,19 @@ BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) { BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) { switch (s) { case zero: + if (!mag.isZero()) + throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude"; + sign = zero; + break; case positive: case negative: + // If the magnitude is zero, force the sign to zero. sign = mag.isZero() ? zero : s; break; default: - throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign"; + /* g++ seems to be optimizing out this case on the assumption + * that the sign is a valid member of the enumeration. Oh well. */ + throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign"; } } @@ -71,23 +85,23 @@ BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf -inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) { - return a.convertToPrimitive(); +inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a, X dummyX) { + return a.convertToPrimitive(dummyX); } template -X BigInteger::convertToUnsignedPrimitive() const { +X BigInteger::convertToUnsignedPrimitive(X dummyX) const { if (sign == negative) throw "BigInteger::to: " "Cannot convert a negative integer to an unsigned type"; else - return convertBigUnsignedToPrimitiveAccess(mag); + return convertBigUnsignedToPrimitiveAccess(mag, dummyX); } /* Similar to BigUnsigned::convertToPrimitive, but split into two cases for * nonnegative and negative numbers. */ template -X BigInteger::convertToSignedPrimitive() const { +X BigInteger::convertToSignedPrimitive(X /*dummyX*/, UX /*dummyUX*/) const { if (sign == zero) return 0; else if (mag.getLength() == 1) { @@ -110,12 +124,12 @@ X BigInteger::convertToSignedPrimitive() const { "Value is too big to fit in the requested type"; } -unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive (); } -unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive (); } -unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive (); } -long BigInteger::toLong () const { return convertToSignedPrimitive (); } -int BigInteger::toInt () const { return convertToSignedPrimitive (); } -short BigInteger::toShort () const { return convertToSignedPrimitive (); } +unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive((unsigned long )0) ; } +unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive((unsigned int )0) ; } +unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive((unsigned short)0) ; } +long BigInteger::toLong () const { return convertToSignedPrimitive ((long )0, (unsigned long )0); } +int BigInteger::toInt () const { return convertToSignedPrimitive ((int )0, (unsigned int )0); } +short BigInteger::toShort () const { return convertToSignedPrimitive ((short)0, (unsigned short)0); } // COMPARISON BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {