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#ifndef BIGUNSIGNED_H 8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define BIGUNSIGNED_H 9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "NumberlikeArray.hh" 11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* A BigUnsigned object represents a nonnegative integer of size limited only by 13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * available memory. BigUnsigneds support most mathematical operators and can 14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * be converted to and from most primitive integer types. 15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The number is stored as a NumberlikeArray of unsigned longs as if it were 17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * written in base 256^sizeof(unsigned long). The least significant block is 18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * first, and the length is such that the most significant block is nonzero. */ 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass BigUnsigned : protected NumberlikeArray<unsigned long> { 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic: 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Enumeration for the result of a comparison. 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov enum CmpRes { less = -1, equal = 0, greater = 1 }; 24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // BigUnsigneds are built with a Blk type of unsigned long. 26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov typedef unsigned long Blk; 27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov typedef NumberlikeArray<Blk>::Index Index; 29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov using NumberlikeArray<Blk>::N; 30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected: 32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Creates a BigUnsigned with a capacity; for internal use. 33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(int, Index c) : NumberlikeArray<Blk>(0, c) {} 34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Decreases len to eliminate any leading zero blocks. 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void zapLeadingZeros() { 37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (len > 0 && blk[len - 1] == 0) 38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len--; 39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic: 42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Constructs zero. 43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned() : NumberlikeArray<Blk>() {} 44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Copy constructor 46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(const BigUnsigned &x) : NumberlikeArray<Blk>(x) {} 47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Assignment operator 49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator=(const BigUnsigned &x) { 50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov NumberlikeArray<Blk>::operator =(x); 51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Constructor that copies from a given array of blocks. 54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(const Blk *b, Index blen) : NumberlikeArray<Blk>(b, blen) { 55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Eliminate any leading zeros we may have been passed. 56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov zapLeadingZeros(); 57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Destructor. NumberlikeArray does the delete for us. 60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ~BigUnsigned() {} 61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Constructors from primitive integer types 63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(unsigned long x); 64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned( long x); 65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(unsigned int x); 66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned( int x); 67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned(unsigned short x); 68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned( short x); 69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected: 70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Helpers 71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov template <class X> void initFromPrimitive (X x); 72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov template <class X> void initFromSignedPrimitive(X x); 73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic: 74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Converters to primitive integer types 76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The implicit conversion operators caused trouble, so these are now 77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * named. */ 78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned long toUnsignedLong () const; 79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov long toLong () const; 80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int toUnsignedInt () const; 81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov int toInt () const; 82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned short toUnsignedShort() const; 83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov short toShort () const; 84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected: 85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Helpers 86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov template <class X> X convertToSignedPrimitive() const; 87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov template <class X> X convertToPrimitive () const; 88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic: 89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // BIT/BLOCK ACCESSORS 91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Expose these from NumberlikeArray directly. 93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov using NumberlikeArray<Blk>::getCapacity; 94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov using NumberlikeArray<Blk>::getLength; 95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Returns the requested block, or 0 if it is beyond the length (as if 97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the number had 0s infinitely to the left). */ 98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; } 99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Sets the requested block. The number grows or shrinks as necessary. */ 100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void setBlock(Index i, Blk newBlock); 101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // The number is zero if and only if the canonical length is zero. 103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool isZero() const { return NumberlikeArray<Blk>::isEmpty(); } 104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Returns the length of the number in bits, i.e., zero if the number 106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * is zero and otherwise one more than the largest value of bi for 107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * which getBit(bi) returns true. */ 108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov Index bitLength() const; 109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Get the state of bit bi, which has value 2^bi. Bits beyond the 110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * number's length are considered to be 0. */ 111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool getBit(Index bi) const { 112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return (getBlock(bi / N) & (Blk(1) << (bi % N))) != 0; 113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Sets the state of bit bi to newBit. The number grows or shrinks as 115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * necessary. */ 116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void setBit(Index bi, bool newBit); 117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // COMPARISONS 119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Compares this to x like Perl's <=> 121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov CmpRes compareTo(const BigUnsigned &x) const; 122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Ordinary comparison operators 124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator ==(const BigUnsigned &x) const { 125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return NumberlikeArray<Blk>::operator ==(x); 126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator !=(const BigUnsigned &x) const { 128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return NumberlikeArray<Blk>::operator !=(x); 129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator < (const BigUnsigned &x) const { return compareTo(x) == less ; } 131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; } 132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less ; } 133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; } 134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* 136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigUnsigned and BigInteger both provide three kinds of operators. 137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Here ``big-integer'' refers to BigInteger or BigUnsigned. 138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (1) Overloaded ``return-by-value'' operators: 140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * +, -, *, /, %, unary -, &, |, ^, <<, >>. 141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Big-integer code using these operators looks identical to code using 142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the primitive integer types. These operators take one or two 143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * big-integer inputs and return a big-integer result, which can then 144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * be assigned to a BigInteger variable or used in an expression. 145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Example: 146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger a(1), b = 1; 147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger c = a + b; 148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (2) Overloaded assignment operators: 150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * +=, -=, *=, /=, %=, flipSign, &=, |=, ^=, <<=, >>=, ++, --. 151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Again, these are used on big integers just like on ints. They take 152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * one writable big integer that both provides an operand and receives a 153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * result. Most also take a second read-only operand. 154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Example: 155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger a(1), b(1); 156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * a += b; 157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (3) Copy-less operations: `add', `subtract', etc. 159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * These named methods take operands as arguments and store the result 160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * in the receiver (*this), avoiding unnecessary copies and allocations. 161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `divideWithRemainder' is special: it both takes the dividend from and 162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * stores the remainder into the receiver, and it takes a separate 163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * object in which to store the quotient. NOTE: If you are wondering 164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * why these don't return a value, you probably mean to use the 165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * overloaded return-by-value operators instead. 166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Examples: 168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger a(43), b(7), c, d; 169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * c = a + b; // Now c == 50. 171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * c.add(a, b); // Same effect but without the two copies. 172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * c.divideWithRemainder(b, d); 174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * // 50 / 7; now d == 7 (quotient) and c == 1 (remainder). 175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * // ``Aliased'' calls now do the right thing using a temporary 177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * // copy, but see note on `divideWithRemainder'. 178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * a.add(a, b); 179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // COPY-LESS OPERATIONS 182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // These 8: Arguments are read-only operands, result is saved in *this. 184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void add(const BigUnsigned &a, const BigUnsigned &b); 185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void subtract(const BigUnsigned &a, const BigUnsigned &b); 186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void multiply(const BigUnsigned &a, const BigUnsigned &b); 187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void bitAnd(const BigUnsigned &a, const BigUnsigned &b); 188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void bitOr(const BigUnsigned &a, const BigUnsigned &b); 189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void bitXor(const BigUnsigned &a, const BigUnsigned &b); 190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Negative shift amounts translate to opposite-direction shifts, 191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * except for -2^(8*sizeof(int)-1) which is unimplemented. */ 192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void bitShiftLeft(const BigUnsigned &a, int b); 193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void bitShiftRight(const BigUnsigned &a, int b); 194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'. 196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * / and % use semantics similar to Knuth's, which differ from the 197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * primitive integer semantics under division by zero. See the 198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * implementation in BigUnsigned.cc for details. 199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `a.divideWithRemainder(b, a)' throws an exception: it doesn't make 200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * sense to write quotient and remainder into the same variable. */ 201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q); 202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* `divide' and `modulo' are no longer offered. Use 204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `divideWithRemainder' instead. */ 205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // OVERLOADED RETURN-BY-VALUE OPERATORS 207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator +(const BigUnsigned &x) const; 208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator -(const BigUnsigned &x) const; 209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator *(const BigUnsigned &x) const; 210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator /(const BigUnsigned &x) const; 211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator %(const BigUnsigned &x) const; 212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* OK, maybe unary minus could succeed in one case, but it really 213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * shouldn't be used, so it isn't provided. */ 214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator &(const BigUnsigned &x) const; 215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator |(const BigUnsigned &x) const; 216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator ^(const BigUnsigned &x) const; 217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator <<(int b) const; 218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned operator >>(int b) const; 219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // OVERLOADED ASSIGNMENT OPERATORS 221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator +=(const BigUnsigned &x); 222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator -=(const BigUnsigned &x); 223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator *=(const BigUnsigned &x); 224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator /=(const BigUnsigned &x); 225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator %=(const BigUnsigned &x); 226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator &=(const BigUnsigned &x); 227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator |=(const BigUnsigned &x); 228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator ^=(const BigUnsigned &x); 229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator <<=(int b); 230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator >>=(int b); 231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* INCREMENT/DECREMENT OPERATORS 233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * To discourage messy coding, these do not return *this, so prefix 234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and postfix behave the same. */ 235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator ++( ); 236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator ++(int); 237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator --( ); 238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void operator --(int); 239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Helper function that needs access to BigUnsigned internals 241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov friend Blk getShiftedBlock(const BigUnsigned &num, Index x, 242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned int y); 243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // See BigInteger.cc. 245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov template <class X> 246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a); 247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}; 248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Implementing the return-by-value and assignment operators in terms of the 250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * copy-less operations. The copy-less operations are responsible for making 251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * any necessary temporary copies to work around aliasing. */ 252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const { 254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.add(*this, x); 256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const { 259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.subtract(*this, x); 261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const { 264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.multiply(*this, x); 266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const { 269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x.isZero()) 270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned q, r; 272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov r = *this; 273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov r.divideWithRemainder(x, q); 274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return q; 275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const { 277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x.isZero()) 278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned q, r; 280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov r = *this; 281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov r.divideWithRemainder(x, q); 282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return r; 283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const { 285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.bitAnd(*this, x); 287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const { 290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.bitOr(*this, x); 292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const { 295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.bitXor(*this, x); 297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator <<(int b) const { 300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.bitShiftLeft(*this, b); 302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline BigUnsigned BigUnsigned::operator >>(int b) const { 305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned ans; 306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ans.bitShiftRight(*this, b); 307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return ans; 308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator +=(const BigUnsigned &x) { 311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov add(*this, x); 312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator -=(const BigUnsigned &x) { 314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov subtract(*this, x); 315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator *=(const BigUnsigned &x) { 317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov multiply(*this, x); 318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator /=(const BigUnsigned &x) { 320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x.isZero()) 321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* The following technique is slightly faster than copying *this first 323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * when x is large. */ 324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned q; 325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov divideWithRemainder(x, q); 326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // *this contains the remainder, but we overwrite it with the quotient. 327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *this = q; 328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator %=(const BigUnsigned &x) { 330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x.isZero()) 331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov BigUnsigned q; 333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Mods *this by x. Don't care about quotient left in q. 334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov divideWithRemainder(x, q); 335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator &=(const BigUnsigned &x) { 337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitAnd(*this, x); 338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator |=(const BigUnsigned &x) { 340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitOr(*this, x); 341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator ^=(const BigUnsigned &x) { 343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitXor(*this, x); 344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator <<=(int b) { 346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitShiftLeft(*this, b); 347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline void BigUnsigned::operator >>=(int b) { 349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov bitShiftRight(*this, b); 350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Templates for conversions of BigUnsigned to and from primitive integers. 353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger.cc needs to instantiate convertToPrimitive, and the uses in 354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigUnsigned.cc didn't do the trick; I think g++ inlined convertToPrimitive 355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * instead of generating linkable instantiations. So for consistency, I put 356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * all the templates here. */ 357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// CONSTRUCTION FROM PRIMITIVE INTEGERS 359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Initialize this BigUnsigned from the given primitive integer. The same 361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * pattern works for all primitive integer types, so I put it into a template to 362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * reduce code duplication. (Don't worry: this is protected and we instantiate 363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * it only with primitive integer types.) Type X could be signed, but x is 364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * known to be nonnegative. */ 365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X> 366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::initFromPrimitive(X x) { 367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x == 0) 368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ; // NumberlikeArray already initialized us to zero. 369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else { 370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Create a single block. blk is NULL; no need to delete it. 371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov cap = 1; 372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk = new Blk[1]; 373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov len = 1; 374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov blk[0] = Blk(x); 375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Ditto, but first check that x is nonnegative. I could have put the check in 379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * initFromPrimitive and let the compiler optimize it out for unsigned-type 380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * instantiations, but I wanted to avoid the warning stupidly issued by g++ for 381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * a condition that is constant in *any* instantiation, even if not in all. */ 382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X> 383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigUnsigned::initFromSignedPrimitive(X x) { 384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x < 0) 385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else 387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov initFromPrimitive(x); 388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// CONVERSION TO PRIMITIVE INTEGERS 391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 392e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Template with the same idea as initFromPrimitive. This might be slightly 393e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * slower than the previous version with the masks, but it's much shorter and 394e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * clearer, which is the library's stated goal. */ 395e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X> 396e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovX BigUnsigned::convertToPrimitive() const { 397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (len == 0) 398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // The number is zero; return zero. 399e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return 0; 400e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else if (len == 1) { 401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // The single block might fit in an X. Try the conversion. 402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov X x = X(blk[0]); 403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Make sure the result accurately represents the block. 404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (Blk(x) == blk[0]) 405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Successful conversion. 406e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return x; 407e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov // Otherwise fall through. 408e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 410e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 411e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 412e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Wrap the above in an x >= 0 test to make sure we got a nonnegative result, 413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * not a negative one that happened to convert back into the correct nonnegative 414e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again, 415e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * separated to avoid a g++ warning. */ 416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X> 417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovX BigUnsigned::convertToSignedPrimitive() const { 418e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov X x = convertToPrimitive<X>(); 419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (x >= 0) 420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return x; 421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov else 422e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov abort(); 423e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 424e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 425e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 426