short toShort () const;
protected:
// Helpers
- template <class X> X convertToSignedPrimitive() const;
- template <class X> X convertToPrimitive () const;
+ template <class X> X convertToSignedPrimitive(X dummyX) const;
+ template <class X> X convertToPrimitive (X dummyX) const;
public:
- // ACCESSORS
+ // BIT/BLOCK ACCESSORS
// Expose these from NumberlikeArray directly.
NumberlikeArray<Blk>::getCapacity;
/* 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<Blk>::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 <=>
// See BigInteger.cc.
template <class X>
- 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
/* 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. */
* slower than the previous version with the masks, but it's much shorter and
* clearer, which is the library's stated goal. */
template <class X>
-X BigUnsigned::convertToPrimitive() const {
+X BigUnsigned::convertToPrimitive(X /*dummyX*/) const {
if (len == 0)
// The number is zero; return zero.
return 0;
* one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again,
* separated to avoid a g++ warning. */
template <class X>
-X BigUnsigned::convertToSignedPrimitive() const {
- X x = convertToPrimitive<X>();
+X BigUnsigned::convertToSignedPrimitive(X dummyX) const {
+ X x = convertToPrimitive(dummyX);
if (x >= 0)
return x;
else