65 for (int32_t i = lhs
.m_length - 1; i >= 0; --i)
104 const uint32_t *pLargeEnd = pLargeCur + largeLen;
106 const uint32_t *pSmallEnd = pSmallCur + smallLen;
108 while (pSmallCur != pSmallEnd)
110 uint64_t sum = carry + (uint64_t)(*pLargeCur) + (uint64_t)(*pSmallCur);
112 (*pResultCur) = sum & 0xFFFFFFFF;
119 while (pLargeCur != pLargeEnd)
121 uint64_t sum = carry + (uint64_t)(*pLargeCur);
123 (*pResultCur) = sum & 0xFFFFFFFF;
132 assert((uint32_t)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
144 assert(pResult != &lhs && pResult != &rhs);
162 assert(maxResultLen <= c_BigInt_MaxBlocks);
165 for (uint32_t *pCur = pResult
->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
170 const uint32_t *pLargeEnd = pLargeBeg + pLarge
->m_length;
175 pSmallCur != pSmallEnd;
176 ++pSmallCur, ++pResultStart)
179 const uint32_t multiplier = *pSmallCur;
182 const uint32_t *pLargeCur = pLargeBeg;
183 uint32_t *pResultCur = pResultStart;
187 uint64_t product = (*pResultCur) + (*pLargeCur) * (uint64_t)multiplier + carry;
188 carry = product >> 32;
189 *pResultCur = product & 0xFFFFFFFF;
192 }
while (pLargeCur != pLargeEnd);
194 assert(pResultCur < pResult->m_blocks + maxResultLen);
195 *pResultCur = (uint32_t)(carry & 0xFFFFFFFF);
200 if (maxResultLen > 0 && pResult
->m_blocks[maxResultLen - 1] == 0)
213 for (; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur)
215 uint64_t product = (uint64_t)(*pLhsCur) * rhs + carry;
216 *pResultCur = (uint32_t)(product & 0xFFFFFFFF);
217 carry = product >> 32;
224 assert(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
225 *pResultCur = (uint32_t)carry;
242 for (; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur)
244 uint32_t cur = *pLhsCur;
245 *pResultCur = (cur << 1) | carry;
252 assert(in.m_length + 1 <= c_BigInt_MaxBlocks);
269 for (; pCur != pEnd; ++pCur)
271 uint32_t cur = *pCur;
272 *pCur = (cur << 1) | carry;
279 assert(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
292 for (; pCur != pEnd; ++pCur)
294 uint64_t product = (uint64_t)(*pCur) * 10ull + carry;
295 (*pCur) = (uint32_t)(product & 0xFFFFFFFF);
296 carry = product >> 32;
302 assert(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
303 *pCur = (uint32_t)carry;
327 {0x6fc10000, 0x002386f2}},
330 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee,
334 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03,
338 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
342 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
353 BigInt *pCurTemp = &temp1;
354 BigInt *pNextTemp = &temp2;
357 uint32_t smallExponent = exponent & 0x7;
362 uint32_t tableIdx = 0;
365 while (exponent != 0)
375 pCurTemp = pNextTemp;
385 *pResult
= *pCurTemp;
396 BigInt *pCurTemp = &temp1;
397 BigInt *pNextTemp = &temp2;
400 uint32_t smallExponent = exponent & 0x7;
401 if (smallExponent != 0)
412 uint32_t tableIdx = 0;
415 while (exponent != 0)
425 pCurTemp = pNextTemp;
435 *pResult
= *pCurTemp;
440 uint32_t blockIdx = exponent / 32;
441 assert(blockIdx < c_BigInt_MaxBlocks);
443 for (uint32_t i = 0; i <= blockIdx; ++i)
448 uint32_t bitIdx = (exponent % 32);
456 assert(!divisor.IsZero() &&
457 divisor.m_blocks[divisor.m_length - 1] >= 8 &&
458 divisor.m_blocks[divisor.m_length - 1] < 0xFFFFFFFF &&
459 pDividend->m_length <= divisor.m_length);
467 const uint32_t *pFinalDivisorBlock = divisor
.m_blocks + length - 1;
468 uint32_t *pFinalDividendBlock = pDividend
->m_blocks + length - 1;
472 uint32_t quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
479 const uint32_t *pDivisorCur = divisor
.m_blocks;
486 uint64_t product = (uint64_t)*pDivisorCur * (uint64_t)quotient + carry;
487 carry = product >> 32;
489 uint64_t difference = (uint64_t)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
490 borrow = (difference >> 32) & 1;
492 *pDividendCur = difference & 0xFFFFFFFF;
496 }
while (pDivisorCur <= pFinalDivisorBlock);
499 while (length > 0 && pDividend
->m_blocks[length - 1] == 0)
512 const uint32_t *pDivisorCur = divisor
.m_blocks;
518 uint64_t difference = (uint64_t)*pDividendCur - (uint64_t)*pDivisorCur - borrow;
519 borrow = (difference >> 32) & 1;
521 *pDividendCur = difference & 0xFFFFFFFF;
525 }
while (pDivisorCur <= pFinalDivisorBlock);
528 while (length > 0 && pDividend
->m_blocks[length - 1] == 0)
541 uint32_t shifboollocks = shift / 32;
542 uint32_t shifboolits = shift % 32;
545 const uint32_t *pInBlocks = pResult
->m_blocks;
547 assert(inLength + shifboollocks < c_BigInt_MaxBlocks);
550 if (shifboolits == 0)
553 for (uint32_t *pInCur = pResult
->m_blocks + inLength, *pOutCur = pInCur + shifboollocks;
561 for (uint32_t i = 0; i < shifboollocks; ++i)
569 int32_t inBlockIdx = inLength - 1;
570 uint32_t ouboollockIdx = inLength + shifboollocks;
573 assert(ouboollockIdx < c_BigInt_MaxBlocks);
577 const uint32_t lowBitsShift = (32 - shifboolits);
578 uint32_t highBits = 0;
579 uint32_t block = pResult
->m_blocks[inBlockIdx];
580 uint32_t lowBits = block >> lowBitsShift;
581 while (inBlockIdx > 0)
583 pResult
->m_blocks[ouboollockIdx] = highBits | lowBits;
584 highBits = block << shifboolits;
590 lowBits = block >> lowBitsShift;
594 assert(ouboollockIdx == shifboollocks + 1);
595 pResult
->m_blocks[ouboollockIdx] = highBits | lowBits;
596 pResult
->m_blocks[ouboollockIdx - 1] = block << shifboolits;
599 for (uint32_t i = 0; i < shifboollocks; ++i)
609 const uint64_t mantissa,
610 const int32_t exponent,
611 const uint32_t mantissaHighBitIdx,
612 const bool hasUnequalMargins,
614 uint32_t cutoffNumber,
617 int32_t *pOutExponent
620 char *pCurDigit = pOubooluffer;
644 BigInt *pScaledMarginHigh;
645 BigInt optionalMarginHigh;
647 if (hasUnequalMargins)
690 pScaledMarginHigh = &optionalMarginHigh;
729 pScaledMarginHigh = &scaledMarginLow;
747 const double log10_2 = 0.30102999566398119521373889472449;
748 int32_t digitExponent = (int32_t)(
ceil(double((int32_t)mantissaHighBitIdx + exponent) * log10_2 - 0.69
));
757 digitExponent = -(int32_t)cutoffNumber + 1;
761 if (digitExponent > 0)
768 else if (digitExponent < 0)
780 scaledMarginLow
= temp;
782 if (pScaledMarginHigh != &scaledMarginLow)
792 digitExponent = digitExponent + 1;
800 if (pScaledMarginHigh != &scaledMarginLow)
806 int32_t cutoffExponent = digitExponent - bufferSize;
816 int32_t desiredCutoffExponent = digitExponent - (int32_t)cutoffNumber;
817 if (desiredCutoffExponent > cutoffExponent)
818 cutoffExponent = desiredCutoffExponent;
825 int32_t desiredCutoffExponent = -(int32_t)cutoffNumber;
826 if (desiredCutoffExponent > cutoffExponent)
827 cutoffExponent = desiredCutoffExponent;
833 *pOutExponent = digitExponent - 1;
842 assert(scale.GetLength() > 0);
844 if (hiBlock < 8 || hiBlock > 429496729)
852 uint32_t hiBlockLog2 =
log2i(hiBlock
);
853 assert(hiBlockLog2 < 3 || hiBlockLog2 > 27);
854 uint32_t shift = (32 + 27 - hiBlockLog2) % 32;
859 if (pScaledMarginHigh != &scaledMarginLow)
867 uint32_t outputDigit;
876 digitExponent = digitExponent - 1;
890 if (low | high | (digitExponent == cutoffExponent))
894 *pCurDigit = (
char)(
'0' + outputDigit);
900 if (pScaledMarginHigh != &scaledMarginLow)
914 digitExponent = digitExponent - 1;
920 if (scaledValue
.IsZero() | (digitExponent == cutoffExponent))
924 *pCurDigit = (
char)(
'0' + outputDigit);
934 bool roundDown = low;
946 roundDown = compare < 0;
950 roundDown = (outputDigit & 1) == 0;
956 *pCurDigit = (
char)(
'0' + outputDigit);
962 if (outputDigit == 9)
968 if (pCurDigit == pOubooluffer)
978 if (*pCurDigit !=
'9')
990 *pCurDigit = (
char)(
'0' + outputDigit + 1);
996 uint32_t outputLen = (uint32_t)(pCurDigit - pOubooluffer);
997 assert(outputLen <= bufferSize);
static void BigInt_ShiftLeft(BigInt *pResult, uint32_t shift)
static void BigInt_Multiply10(BigInt *pResult)
static void BigInt_Multiply2(BigInt *pResult)
double ceil(double x)
Ceiling function.
static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
uint32_t Geboollock(uint32_t idx) const
uint32_t GetLength() const
uint32_t m_blocks[c_BigInt_MaxBlocks]
static void BigInt_Add(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
void SetUInt32(uint32_t val)
unsigned int log2i(unsigned int x)
BigInt & operator=(const BigInt &rhs)
static void BigInt_MultiplyPow10(BigInt *pResult, const BigInt &in, uint32_t exponent)
static int32_t BigInt_Compare(const BigInt &lhs, const BigInt &rhs)
static void BigInt_Multiply2(BigInt *pResult, const BigInt &in)
static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, uint32_t rhs)
uint32_t Dragon4(const uint64_t mantissa, const int32_t exponent, const uint32_t mantissaHighBitIdx, const bool hasUnequalMargins, const tCutoffMode cutoffMode, uint32_t cutoffNumber, char *pOubooluffer, uint32_t bufferSize, int32_t *pOutExponent)
static void BigInt_Pow10(BigInt *pResult, uint32_t exponent)
static uint32_t g_PowerOf10_U32[]
static BigInt g_PowerOf10_Big[]
void SetUInt64(uint64_t val)
static void BigInt_Pow2(BigInt *pResult, uint32_t exponent)
static uint32_t BigInt_DivideWithRemainder_MaxQuotient9(BigInt *pDividend, const BigInt &divisor)