1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file. 4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code by Matt McCutchen, see the LICENSE file. 6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "BigUnsigned.hh" 8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Memory management definitions have moved to the bottom of NumberlikeArray.hh. 10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// The templates used by these constructors and converters are at the bottom of 12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// BigUnsigned.hh. 13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned(unsigned long x) { initFromPrimitive (x); } 15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned(unsigned int x) { initFromPrimitive (x); } 16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned(unsigned short x) { initFromPrimitive (x); } 17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned( long x) { initFromSignedPrimitive(x); } 18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned( int x) { initFromSignedPrimitive(x); } 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::BigUnsigned( short x) { initFromSignedPrimitive(x); } 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned long BigUnsigned::toUnsignedLong () const { return convertToPrimitive <unsigned long >(); } 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned int BigUnsigned::toUnsignedInt () const { return convertToPrimitive <unsigned int >(); } 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned short BigUnsigned::toUnsignedShort() const { return convertToPrimitive <unsigned short>(); } 24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovlong BigUnsigned::toLong () const { return convertToSignedPrimitive< long >(); } 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovint BigUnsigned::toInt () const { return convertToSignedPrimitive< int >(); } 26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovshort BigUnsigned::toShort () const { return convertToSignedPrimitive< short>(); } 27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// BIT/BLOCK ACCESSORS 29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::setBlock(Index i, Blk newBlock) { 31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (newBlock == 0) { 32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (i < len) { 33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = 0; 34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If i >= len, no effect. 37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (i >= len) { 39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // The nonzero block extends the number. 40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocateAndCopy(i+1); 41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zero any added blocks that we aren't setting. 42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (Index j = len; j < i; j++) 43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[j] = 0; 44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = i+1; 45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = newBlock; 47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Evidently the compiler wants BigUnsigned:: on the return type because, at 51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * that point, it hasn't yet parsed the BigUnsigned:: on the name to get the 52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * proper scope. */ 53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::Index BigUnsigned::bitLength() const { 54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (isZero()) 55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return 0; 56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else { 57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk leftmostBlock = getBlock(len - 1); 58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index leftmostBlockLen = 0; 59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (leftmostBlock != 0) { 60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov leftmostBlock >>= 1; 61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov leftmostBlockLen++; 62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return leftmostBlockLen + (len - 1) * N; 64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::setBit(Index bi, bool newBit) { 68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index blockI = bi / N; 69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk block = getBlock(blockI), mask = Blk(1) << (bi % N); 70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov block = newBit ? (block | mask) : (block & ~mask); 71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov setBlock(blockI, block); 72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// COMPARISON 75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const { 76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // A bigger length implies a bigger number. 77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (len < x.len) 78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return less; 79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else if (len > x.len) 80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return greater; 81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else { 82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Compare blocks one by one from left to right. 83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i = len; 84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (i > 0) { 85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov i--; 86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (blk[i] == x.blk[i]) 87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov continue; 88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else if (blk[i] > x.blk[i]) 89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return greater; 90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else 91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return less; 92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If no blocks differed, the numbers are equal. 94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return equal; 95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// COPY-LESS OPERATIONS 99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * On most calls to copy-less operations, it's safe to read the inputs little by 102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * little and write the outputs little by little. However, if one of the 103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * inputs is coming from the same variable into which the output is to be 104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * stored (an "aliased" call), we risk overwriting the input before we read it. 105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * In this case, we first compute the result into a temporary BigUnsigned 106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * variable and then copy it into the requested output variable *this. 107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Each put-here operation uses the DTRT_ALIASED macro (Do The Right Thing on 108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * aliased calls) to generate code for this check. 109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * I adopted this approach on 2007.02.13 (see Assignment Operators in 111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigUnsigned.hh). Before then, put-here operations rejected aliased calls 112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * with an exception. I think doing the right thing is better. 113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Some of the put-here operations can probably handle aliased calls safely 115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * without the extra copy because (for example) they process blocks strictly 116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * right-to-left. At some point I might determine which ones don't need the 117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * copy, but my reasoning would need to be verified very carefully. For now 118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * I'll leave in the copy. 119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define DTRT_ALIASED(cond, op) \ 121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (cond) { \ 122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned tmpThis; \ 123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov tmpThis.op; \ 124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *this = tmpThis; \ 125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; \ 126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::add(const BigUnsigned &a, const BigUnsigned &b) { 131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, add(a, b)); 132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If one argument is zero, copy the other. 133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (a.len == 0) { 134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov operator =(b); 135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else if (b.len == 0) { 137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov operator =(a); 138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Some variables... 141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Carries in and out of an addition stage 142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool carryIn, carryOut; 143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk temp; 144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // a2 points to the longer input, b2 points to the shorter 146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov const BigUnsigned *a2, *b2; 147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (a.len >= b.len) { 148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &a; 149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &b; 150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &b; 152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &a; 153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Set prelimiary length and make room in this BigUnsigned 155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a2->len + 1; 156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each block index that is present in both inputs... 158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0, carryIn = false; i < b2->len; i++) { 159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Add input blocks 160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp = a2->blk[i] + b2->blk[i]; 161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If a rollover occurred, the result is less than either input. 162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // This test is used many times in the BigUnsigned code. 163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryOut = (temp < a2->blk[i]); 164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If a carry was input, handle it 165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (carryIn) { 166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp++; 167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryOut |= (temp == 0); 168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = temp; // Save the addition result 170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryIn = carryOut; // Pass the carry along 171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If there is a carry left over, increase blocks until 173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // one does not roll over. 174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a2->len && carryIn; i++) { 175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp = a2->blk[i] + 1; 176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryIn = (temp == 0); 177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = temp; 178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If the carry was resolved but the larger number 180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // still has blocks, copy them over. 181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a2->len; i++) 182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a2->blk[i]; 183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Set the extra block if there's still a carry, decrease length otherwise 184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (carryIn) 185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = 1; 186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else 187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) { 191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, subtract(a, b)); 192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b.len == 0) { 193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If b is zero, copy a. 194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov operator =(a); 195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else if (a.len < b.len) 197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If a is shorter than b, the result is negative. 198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Some variables... 200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool borrowIn, borrowOut; 201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk temp; 202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Set preliminary length and make room 204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a.len; 205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each block index that is present in both inputs... 207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0, borrowIn = false; i < b.len; i++) { 208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp = a.blk[i] - b.blk[i]; 209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If a reverse rollover occurred, 210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // the result is greater than the block from a. 211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowOut = (temp > a.blk[i]); 212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Handle an incoming borrow 213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (borrowIn) { 214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowOut |= (temp == 0); 215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp--; 216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = temp; // Save the subtraction result 218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowIn = borrowOut; // Pass the borrow along 219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If there is a borrow left over, decrease blocks until 221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // one does not reverse rollover. 222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a.len && borrowIn; i++) { 223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowIn = (a.blk[i] == 0); 224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a.blk[i] - 1; 225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If there's still a borrow, the result is negative. 227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Throw an exception, but zero out this object so as to leave it in a 228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * predictable state. */ 229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (borrowIn) { 230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = 0; 231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else 233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Copy over the rest of the blocks 234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a.len; i++) 235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a.blk[i]; 236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap leading zeros 237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * About the multiplication and division algorithms: 242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * I searched unsucessfully for fast C++ built-in operations like the `b_0' 244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and `c_0' Knuth describes in Section 4.3.1 of ``The Art of Computer 245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Programming'' (replace `place' by `Blk'): 246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * ``b_0[:] multiplication of a one-place integer by another one-place 248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * integer, giving a two-place answer; 249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * ``c_0[:] division of a two-place integer by a one-place integer, 251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * provided that the quotient is a one-place integer, and yielding 252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * also a one-place remainder.'' 253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * I also missed his note that ``[b]y adjusting the word size, if 255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * necessary, nearly all computers will have these three operations 256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * available'', so I gave up on trying to use algorithms similar to his. 257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * A future version of the library might include such algorithms; I 258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * would welcome contributions from others for this. 259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * I eventually decided to use bit-shifting algorithms. To multiply `a' 261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and `b', we zero out the result. Then, for each `1' bit in `a', we 262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * shift `b' left the appropriate amount and add it to the result. 263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Similarly, to divide `a' by `b', we shift `b' left varying amounts, 264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * repeatedly trying to subtract it from `a'. When we succeed, we note 265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the fact by setting a bit in the quotient. While these algorithms 266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * have the same O(n^2) time complexity as Knuth's, the ``constant factor'' 267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * is likely to be larger. 268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Because I used these algorithms, which require single-block addition 270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and subtraction rather than single-block multiplication and division, 271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the innermost loops of all four routines are very similar. Study one 272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * of them and all will become clear. 273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This is a little inline function used by both the multiplication 277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * routine and the division routine. 278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `getShiftedBlock' returns the `x'th block of `num << y'. 280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `y' may be anything from 0 to N - 1, and `x' may be anything from 281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 0 to `num.len'. 282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Two things contribute to this block: 284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (1) The `N - y' low bits of `num.blk[x]', shifted `y' bits left. 286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (2) The `y' high bits of `num.blk[x-1]', shifted `N - y' bits right. 288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * But we must be careful if `x == 0' or `x == num.len', in 290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * which case we should use 0 instead of (2) or (1), respectively. 291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * If `y == 0', then (2) contributes 0, as it should. However, 293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * in some computer environments, for a reason I cannot understand, 294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `a >> b' means `a >> (b % N)'. This means `num.blk[x-1] >> (N - y)' 295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * will return `num.blk[x-1]' instead of the desired 0 when `y == 0'; 296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the test `y == 0' handles this case specially. 297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned::Blk getShiftedBlock(const BigUnsigned &num, 299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned::Index x, unsigned int y) { 300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned::Blk part1 = (x == 0 || y == 0) ? 0 : (num.blk[x - 1] >> (BigUnsigned::N - y)); 301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned::Blk part2 = (x == num.len) ? 0 : (num.blk[x] << y); 302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return part1 | part2; 303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::multiply(const BigUnsigned &a, const BigUnsigned &b) { 306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, multiply(a, b)); 307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // If either a or b is zero, set to zero. 308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (a.len == 0 || b.len == 0) { 309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = 0; 310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Overall method: 314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Set this = 0. 316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * For each 1-bit of `a' (say the `i2'th bit of block `i'): 317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Add `b << (i blocks and i2 bits)' to *this. 318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Variables for the calculation 320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i, j, k; 321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int i2; 322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk temp; 323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool carryIn, carryOut; 324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Set preliminary length and make room 325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a.len + b.len; 326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zero out this object 328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < len; i++) 329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = 0; 330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each block of the first number... 331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < a.len; i++) { 332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each 1-bit of that block... 333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i2 = 0; i2 < N; i2++) { 334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ((a.blk[i] & (Blk(1) << i2)) == 0) 335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov continue; 336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Add b to this, shifted left i blocks and i2 bits. 338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * j is the index in b, and k = i + j is the index in this. 339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `getShiftedBlock', a short inline function defined above, 341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * is now used for the bit handling. It replaces the more 342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * complex `bHigh' code, in which each run of the loop dealt 343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * immediately with the low bits and saved the high bits to 344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * be picked up next time. The last run of the loop used to 345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * leave leftover high bits, which were handled separately. 346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Instead, this loop runs an additional time with j == b.len. 347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * These changes were made on 2005.01.11. 348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (j = 0, k = i, carryIn = false; j <= b.len; j++, k++) { 350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The body of this loop is very similar to the body of the first loop 352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * in `add', except that this loop does a `+=' instead of a `+'. 353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp = blk[k] + getShiftedBlock(b, j, i2); 355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryOut = (temp < blk[k]); 356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (carryIn) { 357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp++; 358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryOut |= (temp == 0); 359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[k] = temp; 361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryIn = carryOut; 362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // No more extra iteration to deal with `bHigh'. 364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Roll-over a carry as necessary. 365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; carryIn; k++) { 366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[k]++; 367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carryIn = (blk[k] == 0); 368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap possible leading zero 372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (blk[len - 1] == 0) 373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * DIVISION WITH REMAINDER 378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This monstrous function mods *this by the given divisor b while storing the 379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * quotient in the given object q; at the end, *this contains the remainder. 380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The seemingly bizarre pattern of inputs and outputs was chosen so that the 381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * function copies as little as possible (since it is implemented by repeated 382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * subtraction of multiples of b from *this). 383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * "modWithQuotient" might be a better name for this function, but I would 385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * rather not change the name now. 386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) { 388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Defending against aliased calls is more complex than usual because we 389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * are writing to both *this and q. 390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * It would be silly to try to write quotient and remainder to the 392e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * same variable. Rule that out right away. */ 393e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (this == &q) 394e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 395e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Now *this and q are separate, so the only concern is that b might be 396e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * aliased to one of them. If so, use a temporary copy of b. */ 397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (this == &b || &q == &b) { 398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned tmpB(b); 399e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov divideWithRemainder(tmpB, q); 400e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Knuth's definition of mod (which this function uses) is somewhat 405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * different from the C++ definition of % in case of division by 0. 406e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 407e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * We let a / 0 == 0 (it doesn't matter much) and a % 0 == a, no 408e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * exceptions thrown. This allows us to preserve both Knuth's demand 409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * that a mod 0 == a and the useful property that 410e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (a / b) * b + (a % b) == a. 411e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 412e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b.len == 0) { 413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.len = 0; 414e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 415e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 418e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * If *this.len < b.len, then *this < b, and we can be sure that b doesn't go into 419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * *this at all. The quotient is 0 and *this is already the remainder (so leave it alone). 420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (len < b.len) { 422e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.len = 0; 423e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 424e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 425e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 426e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // At this point we know (*this).len >= b.len > 0. (Whew!) 427e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 428e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 429e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Overall method: 430e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 431e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * For each appropriate i and i2, decreasing: 432e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Subtract (b << (i blocks and i2 bits)) from *this, storing the 433e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * result in subtractBuf. 434e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * If the subtraction succeeds with a nonnegative result: 435e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Turn on bit i2 of block i of the quotient q. 436e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Copy subtractBuf back into *this. 437e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Otherwise bit i2 of block i remains off, and *this is unchanged. 438e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 439e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Eventually q will contain the entire quotient, and *this will 440e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * be left with the remainder. 441e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 442e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * subtractBuf[x] corresponds to blk[x], not blk[x+i], since 2005.01.11. 443e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * But on a single iteration, we don't touch the i lowest blocks of blk 444e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (and don't use those of subtractBuf) because these blocks are 445e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * unaffected by the subtraction: we are subtracting 446e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (b << (i blocks and i2 bits)), which ends in at least `i' zero 447e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * blocks. */ 448e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Variables for the calculation 449e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i, j, k; 450e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int i2; 451e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk temp; 452e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool borrowIn, borrowOut; 453e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 454e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 455e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Make sure we have an extra zero block just past the value. 456e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 457e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * When we attempt a subtraction, we might shift `b' so 458e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * its first block begins a few bits left of the dividend, 459e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and then we'll try to compare these extra bits with 460e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * a nonexistent block to the left of the dividend. The 461e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * extra zero block ensures sensible behavior; we need 462e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * an extra block in `subtractBuf' for exactly the same reason. 463e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 464e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index origLen = len; // Save real length. 465e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* To avoid an out-of-bounds access in case of reallocation, allocate 466e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * first and then increment the logical length. */ 467e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocateAndCopy(len + 1); 468e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len++; 469e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[origLen] = 0; // Zero the added block. 470e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 471e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // subtractBuf holds part of the result of a subtraction; see above. 472e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk *subtractBuf = new Blk[len]; 473e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 474e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Set preliminary length for quotient and make room 475e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.len = origLen - b.len + 1; 476e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.allocate(q.len); 477e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zero out the quotient 478e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < q.len; i++) 479e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.blk[i] = 0; 480e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 481e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each possible left-shift of b in blocks... 482e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov i = q.len; 483e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (i > 0) { 484e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov i--; 485e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // For each possible left-shift of b in bits... 486e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // (Remember, N is the number of bits in a Blk.) 487e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.blk[i] = 0; 488e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov i2 = N; 489e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (i2 > 0) { 490e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov i2--; 491e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 492e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Subtract b, shifted left i blocks and i2 bits, from *this, 493e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and store the answer in subtractBuf. In the for loop, `k == i + j'. 494e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 495e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Compare this to the middle section of `multiply'. They 496e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * are in many ways analogous. See especially the discussion 497e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * of `getShiftedBlock'. 498e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 499e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (j = 0, k = i, borrowIn = false; j <= b.len; j++, k++) { 500e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp = blk[k] - getShiftedBlock(b, j, i2); 501e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowOut = (temp > blk[k]); 502e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (borrowIn) { 503e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowOut |= (temp == 0); 504e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov temp--; 505e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 506e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Since 2005.01.11, indices of `subtractBuf' directly match those of `blk', so use `k'. 507e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov subtractBuf[k] = temp; 508e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowIn = borrowOut; 509e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 510e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // No more extra iteration to deal with `bHigh'. 511e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Roll-over a borrow as necessary. 512e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; k < origLen && borrowIn; k++) { 513e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrowIn = (blk[k] == 0); 514e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov subtractBuf[k] = blk[k] - 1; 515e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 516e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 517e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * If the subtraction was performed successfully (!borrowIn), 518e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * set bit i2 in block i of the quotient. 519e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 520e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Then, copy the portion of subtractBuf filled by the subtraction 521e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * back to *this. This portion starts with block i and ends-- 522e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * where? Not necessarily at block `i + b.len'! Well, we 523e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * increased k every time we saved a block into subtractBuf, so 524e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the region of subtractBuf we copy is just [i, k). 525e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 526e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (!borrowIn) { 527e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.blk[i] |= (Blk(1) << i2); 528e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (k > i) { 529e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov k--; 530e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[k] = subtractBuf[k]; 531e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 532e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 533e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 534e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 535e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap possible leading zero in quotient 536e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (q.blk[q.len - 1] == 0) 537e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov q.len--; 538e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap any/all leading zeros in remainder 539e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 540e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Deallocate subtractBuf. 541e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // (Thanks to Brad Spencer for noticing my accidental omission of this!) 542e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov delete [] subtractBuf; 543e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 544e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 545e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* BITWISE OPERATORS 546e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * These are straightforward blockwise operations except that they differ in 547e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the output length and the necessity of zapLeadingZeros. */ 548e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 549e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::bitAnd(const BigUnsigned &a, const BigUnsigned &b) { 550e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, bitAnd(a, b)); 551e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // The bitwise & can't be longer than either operand. 552e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = (a.len >= b.len) ? b.len : a.len; 553e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 554e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 555e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < len; i++) 556e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a.blk[i] & b.blk[i]; 557e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 558e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 559e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 560e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::bitOr(const BigUnsigned &a, const BigUnsigned &b) { 561e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, bitOr(a, b)); 562e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 563e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov const BigUnsigned *a2, *b2; 564e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (a.len >= b.len) { 565e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &a; 566e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &b; 567e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 568e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &b; 569e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &a; 570e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 571e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(a2->len); 572e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < b2->len; i++) 573e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a2->blk[i] | b2->blk[i]; 574e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a2->len; i++) 575e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a2->blk[i]; 576e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a2->len; 577e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Doesn't need zapLeadingZeros. 578e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 579e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 580e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::bitXor(const BigUnsigned &a, const BigUnsigned &b) { 581e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a || this == &b, bitXor(a, b)); 582e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 583e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov const BigUnsigned *a2, *b2; 584e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (a.len >= b.len) { 585e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &a; 586e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &b; 587e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 588e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov a2 = &b; 589e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov b2 = &a; 590e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 591e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(a2->len); 592e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < b2->len; i++) 593e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a2->blk[i] ^ b2->blk[i]; 594e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (; i < a2->len; i++) 595e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = a2->blk[i]; 596e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a2->len; 597e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 598e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 599e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 600e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) { 601e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a, bitShiftLeft(a, b)); 602e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b < 0) { 603e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b << 1 == 0) 604e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 605e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else { 606e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitShiftRight(a, -b); 607e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 608e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 609e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 610e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index shiftBlocks = b / N; 611e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int shiftBits = b % N; 612e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // + 1: room for high bits nudged left into another block 613e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a.len + shiftBlocks + 1; 614e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 615e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i, j; 616e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < shiftBlocks; i++) 617e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = 0; 618e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (j = 0, i = shiftBlocks; j <= a.len; j++, i++) 619e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = getShiftedBlock(a, j, shiftBits); 620e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap possible leading zero 621e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (blk[len - 1] == 0) 622e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 623e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 624e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 625e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) { 626e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov DTRT_ALIASED(this == &a, bitShiftRight(a, b)); 627e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b < 0) { 628e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (b << 1 == 0) 629e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 630e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else { 631e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitShiftLeft(a, -b); 632e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 633e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 634e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 635e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // This calculation is wacky, but expressing the shift as a left bit shift 636e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // within each block lets us use getShiftedBlock. 637e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index rightShiftBlocks = (b + N - 1) / N; 638e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int leftShiftBits = N * rightShiftBlocks - b; 639e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Now (N * rightShiftBlocks - leftShiftBits) == b 640e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // and 0 <= leftShiftBits < N. 641e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (rightShiftBlocks >= a.len + 1) { 642e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // All of a is guaranteed to be shifted off, even considering the left 643e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // bit shift. 644e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = 0; 645e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 646e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 647e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Now we're allocating a positive amount. 648e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // + 1: room for high bits nudged left into another block 649e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = a.len + 1 - rightShiftBlocks; 650e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocate(len); 651e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i, j; 652e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (j = rightShiftBlocks, i = 0; j <= a.len; j++, i++) 653e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = getShiftedBlock(a, j, leftShiftBits); 654e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap possible leading zero 655e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (blk[len - 1] == 0) 656e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 657e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 658e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 659e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// INCREMENT/DECREMENT OPERATORS 660e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 661e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Prefix increment 662e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::operator ++() { 663e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 664e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool carry = true; 665e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; i < len && carry; i++) { 666e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i]++; 667e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov carry = (blk[i] == 0); 668e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 669e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (carry) { 670e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Allocate and then increase length, as in divideWithRemainder 671e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov allocateAndCopy(len + 1); 672e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len++; 673e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i] = 1; 674e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 675e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 676e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 677e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Postfix increment: same as prefix 678e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::operator ++(int) { 679e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov operator ++(); 680e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 681e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 682e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Prefix decrement 683e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::operator --() { 684e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (len == 0) 685e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 686e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index i; 687e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool borrow = true; 688e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (i = 0; borrow; i++) { 689e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov borrow = (blk[i] == 0); 690e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[i]--; 691e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 692e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Zap possible leading zero (there can only be one) 693e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (blk[len - 1] == 0) 694e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 695e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 696e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 697e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Postfix decrement: same as prefix 698e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::operator --(int) { 699e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov operator --(); 700e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 701