X-Git-Url: https://mattmccutchen.net/bigint/bigint.git/blobdiff_plain/83a639e66e094c683b48215a895f6d35e9d60d32..refs/heads/no-explicit-template-args:/BigUnsigned.hh diff --git a/BigUnsigned.hh b/BigUnsigned.hh index 0813234..f2b5787 100644 --- a/BigUnsigned.hh +++ b/BigUnsigned.hh @@ -77,11 +77,11 @@ public: short toShort () const; protected: // Helpers - template X convertToSignedPrimitive() const; - template X convertToPrimitive () const; + template X convertToSignedPrimitive(X dummyX) const; + template X convertToPrimitive (X dummyX) const; public: - // ACCESSORS + // BIT/BLOCK ACCESSORS // Expose these from NumberlikeArray directly. NumberlikeArray::getCapacity; @@ -90,10 +90,25 @@ public: /* Returns the requested block, or 0 if it is beyond the length (as if * the number had 0s infinitely to the left). */ Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; } + /* Sets the requested block. The number grows or shrinks as necessary. */ + void setBlock(Index i, Blk newBlock); // The number is zero if and only if the canonical length is zero. bool isZero() const { return NumberlikeArray::isEmpty(); } + /* Returns the length of the number in bits, i.e., zero if the number + * is zero and otherwise one more than the largest value of bi for + * which getBit(bi) returns true. */ + Index bitLength() const; + /* Get the state of bit bi, which has value 2^bi. Bits beyond the + * number's length are considered to be 0. */ + bool getBit(Index bi) const { + return (getBlock(bi / N) & (1 << (bi % N))) != 0; + } + /* Sets the state of bit bi to newBit. The number grows or shrinks as + * necessary. */ + void setBit(Index bi, bool newBit); + // COMPARISONS // Compares this to x like Perl's <=> @@ -222,7 +237,7 @@ public: // See BigInteger.cc. template - friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a); + friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a, X dummyX); }; /* Implementing the return-by-value and assignment operators in terms of the @@ -326,7 +341,7 @@ inline void BigUnsigned::operator >>=(int b) { /* Templates for conversions of BigUnsigned to and from primitive integers. * BigInteger.cc needs to instantiate convertToPrimitive, and the uses in - * BigUnsigned.cc didn't do the trick; I think gcc inlined convertToPrimitive + * BigUnsigned.cc didn't do the trick; I think g++ inlined convertToPrimitive * instead of generating linkable instantiations. So for consistency, I put * all the templates here. */ @@ -369,7 +384,7 @@ void BigUnsigned::initFromSignedPrimitive(X x) { * slower than the previous version with the masks, but it's much shorter and * clearer, which is the library's stated goal. */ template -X BigUnsigned::convertToPrimitive() const { +X BigUnsigned::convertToPrimitive(X /*dummyX*/) const { if (len == 0) // The number is zero; return zero. return 0; @@ -391,8 +406,8 @@ X BigUnsigned::convertToPrimitive() const { * one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again, * separated to avoid a g++ warning. */ template -X BigUnsigned::convertToSignedPrimitive() const { - X x = convertToPrimitive(); +X BigUnsigned::convertToSignedPrimitive(X dummyX) const { + X x = convertToPrimitive(dummyX); if (x >= 0) return x; else