//---------------------------------------------------------------------------------------------------------------------- // // Handing signed integer of arbitrary size // // This file is part of libpm library // // Copyright (C) 2015, ..., 2019 Pierre Molinaro. // // e-mail : pierre@pcmolinaro.name // // This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General // Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope it will be useful, but WITHOUT ANY WARRANTY; without even the implied // warranty of MERCHANDIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // //---------------------------------------------------------------------------------------------------------------------- #include "utilities/C_BigInt.h" #include "strings/C_String.h" //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Default constructor, destructor, copy #endif //---------------------------------------------------------------------------------------------------------------------- // Default Constructor: init to zero //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (void) : mGMPint () { mpz_init (mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------------------------------------------------------- C_BigInt::~C_BigInt (void) { mpz_clear (mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- // Handle copy //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (const C_BigInt & inOperand) : mGMPint () { mpz_init (mGMPint) ; mpz_set (mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt & C_BigInt::operator = (const C_BigInt & inOperand) { if (this != & inOperand) { mpz_set (mGMPint, inOperand.mGMPint) ; } return *this ; } //---------------------------------------------------------------------------------------------------------------------- // Normalize and tests //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Tests #endif //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::isZero (void) const { return mpz_cmp_ui (mGMPint, 0) == 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::isOne (void) const { return mpz_cmp_ui (mGMPint, 1) == 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::isMinusOne (void) const { return mpz_cmp_si (mGMPint, -1) == 0 ; } //---------------------------------------------------------------------------------------------------------------------- int32_t C_BigInt::sign (void) const { return mpz_sgn (mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::isNegative (void) const { return sign () < 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::isPositive (void) const { return sign () > 0 ; } //---------------------------------------------------------------------------------------------------------------------- // Constructors //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Constructors #endif //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (const uint64_t inValue, const bool inNegate) : mGMPint () { mpz_init (mGMPint) ; const uint64_t high = inValue >> 32 ; if (high == 0) { mpz_set_ui (mGMPint, (uint32_t) inValue) ; }else{ mpz_set_ui (mGMPint, (uint32_t) high) ; mpz_mul_2exp (mGMPint, mGMPint, 32) ; mpz_add_ui (mGMPint, mGMPint, (uint32_t) (inValue & UINT32_MAX)) ; } if (inNegate) { mpz_neg (mGMPint, mGMPint) ; } } //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (const uint64_t inHighValue, const uint64_t inLowValue, const bool inNegate) : mGMPint () { mpz_init (mGMPint) ; mpz_set_ui (mGMPint, 0) ; if (inHighValue != 0) { const uint64_t high = inHighValue >> 32 ; if (high == 0) { mpz_set_ui (mGMPint, (uint32_t) inHighValue) ; }else{ mpz_set_ui (mGMPint, (uint32_t) high) ; mpz_mul_2exp (mGMPint, mGMPint, 32) ; mpz_add_ui (mGMPint, mGMPint, (uint32_t) (inHighValue & UINT32_MAX)) ; } mpz_mul_2exp (mGMPint, mGMPint, 32) ; } const uint64_t high = inLowValue >> 32 ; mpz_add_ui (mGMPint, mGMPint, (uint32_t) high) ; mpz_mul_2exp (mGMPint, mGMPint, 32) ; mpz_add_ui (mGMPint, mGMPint, (uint32_t) (inLowValue & UINT32_MAX)) ; if (inNegate) { mpz_neg (mGMPint, mGMPint) ; } } //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (const int64_t inValue) : mGMPint () { const bool negative = inValue < 0 ; const uint64_t v = (uint64_t) (negative ? (- inValue) : inValue) ; mpz_init (mGMPint) ; const uint64_t high = v >> 32 ; if (high == 0) { mpz_set_ui (mGMPint, (uint32_t) v) ; }else{ mpz_set_ui (mGMPint, (uint32_t) high) ; mpz_mul_2exp (mGMPint, mGMPint, 32) ; mpz_add_ui (mGMPint, mGMPint, (uint32_t) (v & UINT32_MAX)) ; } if (negative) { mpz_neg (mGMPint, mGMPint) ; } } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::setToZero (void) { mpz_set_ui (mGMPint, 0) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::setFromUnsigned (const uint32_t inValue) { mpz_set_ui (mGMPint, inValue) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt::C_BigInt (const char * inString, const int32_t inBase, bool & outOk) : mGMPint () { mpz_init (mGMPint) ; const int r = mpz_set_str (mGMPint, inString, inBase) ; outOk = r == 0 ; } //---------------------------------------------------------------------------------------------------------------------- // increment //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Increment, decrement #endif //---------------------------------------------------------------------------------------------------------------------- C_BigInt & C_BigInt::operator ++ (void) { mpz_add_ui (mGMPint, mGMPint, 1) ; return *this ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt & C_BigInt::operator -- (void) { mpz_sub_ui (mGMPint, mGMPint, 1) ; return *this ; } //---------------------------------------------------------------------------------------------------------------------- // String //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Convert to string #endif //---------------------------------------------------------------------------------------------------------------------- C_String C_BigInt::decimalString (void) const { const size_t neededSize = mpz_sizeinbase (mGMPint, 10) + 2 ; char * s = NULL ; macroMyNewPODArray (s, char, neededSize) ; mpz_get_str (s, 10, mGMPint) ; C_String result ; result << s ; macroMyDeletePODArray (s) ; return result ; } //---------------------------------------------------------------------------------------------------------------------- C_String C_BigInt::spacedDecimalString (const uint32_t inSeparation) const { C_String result = decimalString () ; if (inSeparation > 0) { const bool valueIsNegative = sign () < 0 ; const int32_t lowBound = valueIsNegative ? 1 : 0 ; for (int32_t i = result.length () - (int32_t) inSeparation ; i > lowBound ; i -= (int32_t) inSeparation) { result.insertCharacterAtIndex (' ', i COMMA_HERE) ; } } return result ; } //---------------------------------------------------------------------------------------------------------------------- C_String C_BigInt::hexString (void) const { C_String result ; if (sign () >= 0) { result << "0x" << xString () ; }else{ result << "-0x" << abs ().xString () ; } return result ; } //---------------------------------------------------------------------------------------------------------------------- C_String C_BigInt::xString (void) const { char * s = NULL ; const size_t neededSize = mpz_sizeinbase (mGMPint, 16) + 2 ; macroMyNewPODArray (s, char, neededSize) ; mpz_get_str (s, -16, mGMPint) ; // -16 for getting 'A' to 'F' (16 provides 'a' to 'f') C_String result ; result << s ; macroMyDeletePODArray (s) ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Absolute value #endif //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::abs (void) const { C_BigInt result ; mpz_abs (result.mGMPint, mGMPint) ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Logical operations #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator &= (const C_BigInt inOperand) { mpz_and (mGMPint, mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator & (const C_BigInt & inOperand) const { C_BigInt result = *this ; result &= inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator |= (const C_BigInt inOperand) { mpz_ior (mGMPint, mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator | (const C_BigInt & inOperand) const { C_BigInt result = *this ; result |= inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator ^= (const C_BigInt inOperand) { mpz_xor (mGMPint, mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator ^ (const C_BigInt & inOperand) const { C_BigInt result = *this ; result ^= inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator ~ (void) const { C_BigInt result ; mpz_com (result.mGMPint, mGMPint) ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Add, subtract uint32_t #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator += (const uint32_t inOperand) { mpz_add_ui (mGMPint, mGMPint, inOperand) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator + (const uint32_t inOperand) const { C_BigInt result = *this ; result += inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator -= (const uint32_t inOperand) { mpz_sub_ui (mGMPint, mGMPint, inOperand) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator - (const uint32_t inOperand) const { C_BigInt result = *this ; result -= inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Add, subtract C_BigInt #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator += (const C_BigInt inOperand) { mpz_add (mGMPint, mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator -= (const C_BigInt inOperand) { mpz_sub (mGMPint, mGMPint, inOperand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator + (const C_BigInt & inOperand) const { C_BigInt result = *this ; result += inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator - (const C_BigInt & inOperand) const { C_BigInt result = *this ; result -= inOperand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- // Negate //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Negate #endif //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator - (void) const { C_BigInt result = *this ; result.negateInPlace () ; return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::negateInPlace (void) { mpz_neg (mGMPint, mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Multiplication with uint32_t #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator *= (const uint32_t inMultiplicand) { mpz_mul_ui (mGMPint, mGMPint, inMultiplicand) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator * (const uint32_t inMultiplicand) const { C_BigInt result = *this ; result *= inMultiplicand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Multiplication with C_BigInt #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator *= (const C_BigInt inMultiplicand) { mpz_mul (mGMPint, mGMPint, inMultiplicand.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator * (const C_BigInt & inMultiplicand) const { C_BigInt result = *this ; result *= inMultiplicand ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Division #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::divideBy (const uint32_t inDivisor, C_BigInt & outQuotient, uint32_t & outRemainder) const { outRemainder = (uint32_t) mpz_fdiv_q_ui (outQuotient.mGMPint, mGMPint, inDivisor) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::divideInPlace (const uint32_t inDivisor, uint32_t & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; if (mpz_sgn (mGMPint) >= 0) { outRemainder = (uint32_t) mpz_fdiv_q_ui (quotient, mGMPint, inDivisor) ; }else{ outRemainder = (uint32_t) mpz_cdiv_q_ui (quotient, mGMPint, inDivisor) ; } mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::divideBy (const C_BigInt inDivisor, C_BigInt & outQuotient, C_BigInt & outRemainder) const { outQuotient = *this ; outQuotient.divideInPlace (inDivisor, outRemainder) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::divideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; mpz_tdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ; mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::ceilDivideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; mpz_cdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ; mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::ceilDivideBy (const C_BigInt inDivisor, C_BigInt & outQuotient, C_BigInt & outRemainder) const { outQuotient = *this ; outQuotient.ceilDivideInPlace (inDivisor, outRemainder) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::floorDivideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; mpz_fdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ; mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::floorDivideBy (const C_BigInt inDivisor, C_BigInt & outQuotient, C_BigInt & outRemainder) const { outQuotient = *this ; outQuotient.floorDivideInPlace (inDivisor, outRemainder) ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator /= (const C_BigInt inDivisor) { C_BigInt unusedRemainder ; divideInPlace (inDivisor, unusedRemainder) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator / (const C_BigInt & inDivisor) const { C_BigInt result = *this ; result /= inDivisor ; return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator %= (const C_BigInt inDivisor) { mpz_t quotient ; mpz_init (quotient) ; mpz_t remainder ; mpz_init (remainder) ; mpz_tdiv_qr (quotient, remainder, mGMPint, inDivisor.mGMPint) ; mpz_swap (remainder, mGMPint) ; mpz_clear (quotient) ; mpz_clear (remainder) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator % (const C_BigInt & inDivisor) const { C_BigInt result = *this ; result %= inDivisor ; return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Shift left #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator <<= (const uint32_t inValue) { mpz_mul_2exp (mGMPint, mGMPint, inValue) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator << (const uint32_t inValue) const { C_BigInt result = *this ; result <<= inValue ; return result ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator << (const C_BigInt inValue) const { C_BigInt result = *this ; if (inValue > C_BigInt (0)) { const uint32_t v = inValue.uint32 () ; result <<= v ; } return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Shift right #endif //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::operator >>= (const uint32_t inValue) { mpz_t quotient ; mpz_init (quotient) ; mpz_fdiv_q_2exp (quotient, mGMPint, inValue) ; mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator >> (const uint32_t inValue) const { C_BigInt result = *this ; result >>= inValue ; return result ; } //---------------------------------------------------------------------------------------------------------------------- C_BigInt C_BigInt::operator >> (const C_BigInt inValue) const { C_BigInt result = *this ; if (inValue > C_BigInt (0)) { const uint32_t v = inValue.uint32 () ; result >>= v ; } return result ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Compare #endif //---------------------------------------------------------------------------------------------------------------------- int32_t C_BigInt::compare (const C_BigInt & inValue) const { return mpz_cmp (mGMPint, inValue.mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator == (const C_BigInt & inOperand) const { return compare (inOperand) == 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator != (const C_BigInt & inOperand) const { return compare (inOperand) != 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator >= (const C_BigInt & inOperand) const { return compare (inOperand) >= 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator > (const C_BigInt & inOperand) const { return compare (inOperand) > 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator <= (const C_BigInt & inOperand) const { return compare (inOperand) <= 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::operator < (const C_BigInt & inOperand) const { return compare (inOperand) < 0 ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Bit manipulation #endif //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::bitAtIndex (const uint32_t inIndex) const { return mpz_tstbit (mGMPint, inIndex) != 0 ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::setBitAtIndex (const bool inBit, const uint32_t inIndex) { if (inBit) { mpz_setbit (mGMPint, inIndex) ; }else{ mpz_clrbit (mGMPint, inIndex) ; } } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::complementBitAtIndex (const uint32_t inIndex) { mpz_combit (mGMPint, inIndex) ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Testing Value #endif //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::fitsInUInt32 (void) const { return mpz_fits_uint_p (mGMPint) != 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::fitsInUInt64 (void) const { return (mpz_sgn (mGMPint) >= 0) && (mpz_sizeinbase (mGMPint, 2) <= 64) ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::fitsInSInt32 (void) const { return mpz_fits_sint_p (mGMPint) != 0 ; } //---------------------------------------------------------------------------------------------------------------------- bool C_BigInt::fitsInSInt64 (void) const { const size_t requiredBitCount = mpz_sizeinbase (mGMPint, 2) ; bool ok = requiredBitCount <= 63 ; if ((requiredBitCount == 64) && (mpz_sgn (mGMPint) < 0)) { // INT64_MIN is a particular case int64_t r ; mpz_export (& r, NULL, 1, sizeof (int64_t), 0, 0, mGMPint) ; ok = r == INT64_MIN ; } return ok ; } //---------------------------------------------------------------------------------------------------------------------- uint32_t C_BigInt::requiredBitCountForSignedRepresentation (void) const { size_t requiredBitCount = mpz_sizeinbase (mGMPint, 2) ; if (mpz_sgn (mGMPint) > 0) { requiredBitCount ++ ; } return (uint32_t) requiredBitCount ; } //---------------------------------------------------------------------------------------------------------------------- uint32_t C_BigInt::requiredBitCountForUnsignedRepresentation (void) const { return (uint32_t) mpz_sizeinbase (mGMPint, 2) ; } //---------------------------------------------------------------------------------------------------------------------- #ifdef PRAGMA_MARK_ALLOWED #pragma mark Value access #endif //---------------------------------------------------------------------------------------------------------------------- uint32_t C_BigInt::uint32 (void) const { return (uint32_t) mpz_get_ui (mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- uint64_t C_BigInt::uint64 (void) const { uint64_t result = 0 ; if (! isZero ()) { result = UINT64_MAX ; if (fitsInUInt64 ()) { mpz_export (& result, NULL, 1, sizeof (uint64_t), 0, 0, mGMPint) ; } } return result ; } //---------------------------------------------------------------------------------------------------------------------- int32_t C_BigInt::int32 (void) const { return (int32_t) mpz_get_si (mGMPint) ; } //---------------------------------------------------------------------------------------------------------------------- //mpz_export (void *r, size_t *countp, int order, size_t size, int endian, // size_t nails, const mpz_t u) int64_t C_BigInt::int64 (void) const { int64_t result = 0 ; if (! isZero ()) { uint64_t r = UINT64_MAX ; if (fitsInSInt64 ()) { mpz_export (& r, NULL, 1, sizeof (uint64_t), 0, 0, mGMPint) ; } result = int64_t (r) ; if (mpz_sgn (mGMPint) < 0) { result = - result ; } } return result ; } //---------------------------------------------------------------------------------------------------------------------- void C_BigInt::extractBytesForUnsignedRepresentation (TC_UniqueArray & outValue) const { size_t count = 0 ; const uint8_t * ptr = (const uint8_t *) mpz_export (NULL, & count, -1, sizeof (uint8_t), 0, 0, mGMPint) ; outValue.setCountToZero () ; for (size_t i=0 ; i & outValue) const { if (mpz_sgn (mGMPint) == 0) { // zero outValue.setCountToZero () ; outValue.appendObject (0) ; }else if (mpz_sgn (mGMPint) > 0) { // > 0 extractBytesForUnsignedRepresentation (outValue) ; if ((outValue.lastObject (HERE) & 0x80) != 0) { outValue.appendObject (0) ; } }else{ // < 0 extractBytesForUnsignedRepresentation (outValue) ; //--- Perform two's complement uint8_t carry = 1 ; for (int32_t i=0 ; i