X-Git-Url: https://mattmccutchen.net/bigint/bigint.git/blobdiff_plain/83a639e66e094c683b48215a895f6d35e9d60d32..refs/heads/no-explicit-template-args:/BigUnsigned.cc diff --git a/BigUnsigned.cc b/BigUnsigned.cc index a4e6d9b..aa7e691 100644 --- a/BigUnsigned.cc +++ b/BigUnsigned.cc @@ -12,12 +12,58 @@ BigUnsigned::BigUnsigned( long x) { initFromSignedPrimitive(x); } BigUnsigned::BigUnsigned( int x) { initFromSignedPrimitive(x); } BigUnsigned::BigUnsigned( short x) { initFromSignedPrimitive(x); } -unsigned long BigUnsigned::toUnsignedLong () const { return convertToPrimitive (); } -unsigned int BigUnsigned::toUnsignedInt () const { return convertToPrimitive (); } -unsigned short BigUnsigned::toUnsignedShort() const { return convertToPrimitive (); } -long BigUnsigned::toLong () const { return convertToSignedPrimitive< long >(); } -int BigUnsigned::toInt () const { return convertToSignedPrimitive< int >(); } -short BigUnsigned::toShort () const { return convertToSignedPrimitive< short>(); } +unsigned long BigUnsigned::toUnsignedLong () const { return convertToPrimitive ((unsigned long )0); } +unsigned int BigUnsigned::toUnsignedInt () const { return convertToPrimitive ((unsigned int )0); } +unsigned short BigUnsigned::toUnsignedShort() const { return convertToPrimitive ((unsigned short)0); } +long BigUnsigned::toLong () const { return convertToSignedPrimitive(( long )0); } +int BigUnsigned::toInt () const { return convertToSignedPrimitive(( int )0); } +short BigUnsigned::toShort () const { return convertToSignedPrimitive(( short)0); } + +// BIT/BLOCK ACCESSORS + +void BigUnsigned::setBlock(Index i, Blk newBlock) { + if (newBlock == 0) { + if (i < len) { + blk[i] = 0; + zapLeadingZeros(); + } + // If i >= len, no effect. + } else { + if (i >= len) { + // The nonzero block extends the number. + allocateAndCopy(i+1); + // Zero any added blocks that we aren't setting. + for (Index j = len; j < i; j++) + blk[j] = 0; + len = i+1; + } + blk[i] = newBlock; + } +} + +/* Evidently the compiler wants BigUnsigned:: on the return type because, at + * that point, it hasn't yet parsed the BigUnsigned:: on the name to get the + * proper scope. */ +BigUnsigned::Index BigUnsigned::bitLength() const { + if (isZero()) + return 0; + else { + Blk leftmostBlock = getBlock(len - 1); + Index leftmostBlockLen = 0; + while (leftmostBlock != 0) { + leftmostBlock >>= 1; + leftmostBlockLen++; + } + return leftmostBlockLen + (len - 1) * N; + } +} + +void BigUnsigned::setBit(Index bi, bool newBit) { + Index blockI = bi / N; + Blk block = getBlock(blockI), mask = 1 << (bi % N); + block = newBit ? (block | mask) : (block & ~mask); + setBlock(blockI, block); +} // COMPARISON BigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const {