amath  1.8.5
Simple command line calculator
bigint.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 /*
31  * Copyright (c) 2014 Ryan Juckett
32  * http://www.ryanjuckett.com/
33  *
34  * This software is provided 'as-is', without any express or implied
35  * warranty. In no event will the authors be held liable for any damages
36  * arising from the use of this software.
37  *
38  * Permission is granted to anyone to use this software for any purpose,
39  * including commercial applications, and to alter it and redistribute it
40  * freely, subject to the following restrictions:
41  *
42  * 1. The origin of this software must not be misrepresented; you must not
43  * claim that you wrote the original software. If you use this software
44  * in a product, an acknowledgment in the product documentation would be
45  * appreciated but is not required.
46  *
47  * 2. Altered source versions must be plainly marked as such, and must not
48  * be misrepresented as being the original software.
49  *
50  * 3. This notice may not be removed or altered from any source
51  * distribution.
52  */
53 
54 #include "bigint.h"
55 #include "mathr.h"
56 
57 static int32_t BigInt_Compare(const BigInt &lhs, const BigInt &rhs)
58 {
59  // A bigger length implies a bigger number.
60  int32_t lengthDiff = lhs.m_length - rhs.m_length;
61  if (lengthDiff != 0)
62  return lengthDiff;
63 
64  // Compare blocks one by one from high to low.
65  for (int32_t i = lhs.m_length - 1; i >= 0; --i)
66  {
67  if (lhs.m_blocks[i] == rhs.m_blocks[i])
68  continue;
69  else if (lhs.m_blocks[i] > rhs.m_blocks[i])
70  return 1;
71  else
72  return -1;
73  }
74 
75  // no blocks differed
76  return 0;
77 }
78 
79 static void BigInt_Add(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
80 {
81  // determine which operand has the smaller length
82  const BigInt *pLarge;
83  const BigInt *pSmall;
84  if (lhs.m_length < rhs.m_length)
85  {
86  pSmall = &lhs;
87  pLarge = &rhs;
88  }
89  else
90  {
91  pSmall = &rhs;
92  pLarge = &lhs;
93  }
94 
95  const uint32_t largeLen = pLarge->m_length;
96  const uint32_t smallLen = pSmall->m_length;
97 
98  // The output will be at least as long as the largest input
99  pResult->m_length = largeLen;
100 
101  // Add each block and add carry the overflow to the next block
102  uint64_t carry = 0;
103  const uint32_t *pLargeCur = pLarge->m_blocks;
104  const uint32_t *pLargeEnd = pLargeCur + largeLen;
105  const uint32_t *pSmallCur = pSmall->m_blocks;
106  const uint32_t *pSmallEnd = pSmallCur + smallLen;
107  uint32_t *pResultCur = pResult->m_blocks;
108  while (pSmallCur != pSmallEnd)
109  {
110  uint64_t sum = carry + (uint64_t)(*pLargeCur) + (uint64_t)(*pSmallCur);
111  carry = sum >> 32;
112  (*pResultCur) = sum & 0xFFFFFFFF;
113  ++pLargeCur;
114  ++pSmallCur;
115  ++pResultCur;
116  }
117 
118  // Add the carry to any blocks that only exist in the large operand
119  while (pLargeCur != pLargeEnd)
120  {
121  uint64_t sum = carry + (uint64_t)(*pLargeCur);
122  carry = sum >> 32;
123  (*pResultCur) = sum & 0xFFFFFFFF;
124  ++pLargeCur;
125  ++pResultCur;
126  }
127 
128  // If there's still a carry, append a new block
129  if (carry != 0)
130  {
131  assert(carry == 1);
132  assert((uint32_t)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
133  *pResultCur = 1;
134  pResult->m_length = largeLen + 1;
135  }
136  else
137  {
138  pResult->m_length = largeLen;
139  }
140 }
141 
142 static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
143 {
144  assert(pResult != &lhs && pResult != &rhs);
145 
146  // determine which operand has the smaller length
147  const BigInt *pLarge;
148  const BigInt *pSmall;
149  if (lhs.m_length < rhs.m_length)
150  {
151  pSmall = &lhs;
152  pLarge = &rhs;
153  }
154  else
155  {
156  pSmall = &rhs;
157  pLarge = &lhs;
158  }
159 
160  // set the maximum possible result length
161  uint32_t maxResultLen = pLarge->m_length + pSmall->m_length;
162  assert(maxResultLen <= c_BigInt_MaxBlocks);
163 
164  // clear the result data
165  for (uint32_t *pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
166  *pCur = 0;
167 
168  // perform standard long multiplication
169  const uint32_t *pLargeBeg = pLarge->m_blocks;
170  const uint32_t *pLargeEnd = pLargeBeg + pLarge->m_length;
171 
172  // for each small block
173  uint32_t *pResultStart = pResult->m_blocks;
174  for (const uint32_t *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length;
175  pSmallCur != pSmallEnd;
176  ++pSmallCur, ++pResultStart)
177  {
178  // if non-zero, multiply against all the large blocks and add into the result
179  const uint32_t multiplier = *pSmallCur;
180  if (multiplier != 0)
181  {
182  const uint32_t *pLargeCur = pLargeBeg;
183  uint32_t *pResultCur = pResultStart;
184  uint64_t carry = 0;
185  do
186  {
187  uint64_t product = (*pResultCur) + (*pLargeCur) * (uint64_t)multiplier + carry;
188  carry = product >> 32;
189  *pResultCur = product & 0xFFFFFFFF;
190  ++pLargeCur;
191  ++pResultCur;
192  } while (pLargeCur != pLargeEnd);
193 
194  assert(pResultCur < pResult->m_blocks + maxResultLen);
195  *pResultCur = (uint32_t)(carry & 0xFFFFFFFF);
196  }
197  }
198 
199  // check if the terminating block has no set bits
200  if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0)
201  pResult->m_length = maxResultLen - 1;
202  else
203  pResult->m_length = maxResultLen;
204 }
205 
206 static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, uint32_t rhs)
207 {
208  // perform long multiplication
209  uint32_t carry = 0;
210  uint32_t *pResultCur = pResult->m_blocks;
211  const uint32_t *pLhsCur = lhs.m_blocks;
212  const uint32_t *pLhsEnd = lhs.m_blocks + lhs.m_length;
213  for (; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur)
214  {
215  uint64_t product = (uint64_t)(*pLhsCur) * rhs + carry;
216  *pResultCur = (uint32_t)(product & 0xFFFFFFFF);
217  carry = product >> 32;
218  }
219 
220  // if there is a remaining carry, grow the array
221  if (carry != 0)
222  {
223  // grow the array
224  assert(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
225  *pResultCur = (uint32_t)carry;
226  pResult->m_length = lhs.m_length + 1;
227  }
228  else
229  {
230  pResult->m_length = lhs.m_length;
231  }
232 }
233 
234 static void BigInt_Multiply2(BigInt *pResult, const BigInt &in)
235 {
236  // shift all the blocks by one
237  uint32_t carry = 0;
238 
239  uint32_t *pResultCur = pResult->m_blocks;
240  const uint32_t *pLhsCur = in.m_blocks;
241  const uint32_t *pLhsEnd = in.m_blocks + in.m_length;
242  for (; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur)
243  {
244  uint32_t cur = *pLhsCur;
245  *pResultCur = (cur << 1) | carry;
246  carry = cur >> 31;
247  }
248 
249  if (carry != 0)
250  {
251  // grow the array
252  assert(in.m_length + 1 <= c_BigInt_MaxBlocks);
253  *pResultCur = carry;
254  pResult->m_length = in.m_length + 1;
255  }
256  else
257  {
258  pResult->m_length = in.m_length;
259  }
260 }
261 
262 static void BigInt_Multiply2(BigInt *pResult)
263 {
264  // shift all the blocks by one
265  uint32_t carry = 0;
266 
267  uint32_t *pCur = pResult->m_blocks;
268  uint32_t *pEnd = pResult->m_blocks + pResult->m_length;
269  for (; pCur != pEnd; ++pCur)
270  {
271  uint32_t cur = *pCur;
272  *pCur = (cur << 1) | carry;
273  carry = cur >> 31;
274  }
275 
276  if (carry != 0)
277  {
278  // grow the array
279  assert(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
280  *pCur = carry;
281  ++pResult->m_length;
282  }
283 }
284 
285 static void BigInt_Multiply10(BigInt *pResult)
286 {
287  // multiply all the blocks
288  uint64_t carry = 0;
289 
290  uint32_t *pCur = pResult->m_blocks;
291  uint32_t *pEnd = pResult->m_blocks + pResult->m_length;
292  for (; pCur != pEnd; ++pCur)
293  {
294  uint64_t product = (uint64_t)(*pCur) * 10ull + carry;
295  (*pCur) = (uint32_t)(product & 0xFFFFFFFF);
296  carry = product >> 32;
297  }
298 
299  if (carry != 0)
300  {
301  // grow the array
302  assert(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
303  *pCur = (uint32_t)carry;
304  ++pResult->m_length;
305  }
306 }
307 
308 static uint32_t g_PowerOf10_U32[] =
309  {
310  1, // 10 ^ 0
311  10, // 10 ^ 1
312  100, // 10 ^ 2
313  1000, // 10 ^ 3
314  10000, // 10 ^ 4
315  100000, // 10 ^ 5
316  1000000, // 10 ^ 6
317  10000000, // 10 ^ 7
318 };
319 
321  {
322  // 10 ^ 8
323  {1,
324  {100000000}},
325  // 10 ^ 16
326  {2,
327  {0x6fc10000, 0x002386f2}},
328  // 10 ^ 32
329  {4, {
330  0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee,
331  }},
332  // 10 ^ 64
333  {7, {
334  0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03,
335  }},
336  // 10 ^ 128
337  {14, {
338  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
339  }},
340  // 10 ^ 256
341  {27, {
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,
343  }}};
344 
345 static void BigInt_Pow10(BigInt *pResult, uint32_t exponent)
346 {
347  // make sure the exponent is within the bounds of the lookup table data
348  assert(exponent < 512);
349 
350  // create two temporary values to reduce large integer copy operations
351  BigInt temp1;
352  BigInt temp2;
353  BigInt *pCurTemp = &temp1;
354  BigInt *pNextTemp = &temp2;
355 
356  // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
357  uint32_t smallExponent = exponent & 0x7;
358  pCurTemp->SetUInt32(g_PowerOf10_U32[smallExponent]);
359 
360  // remove the low bits that we used for the 32-bit lookup table
361  exponent >>= 3;
362  uint32_t tableIdx = 0;
363 
364  // while there are remaining bits in the exponent to be processed
365  while (exponent != 0)
366  {
367  // if the current bit is set, multiply it with the corresponding power of 10
368  if (exponent & 1)
369  {
370  // multiply into the next temporary
371  BigInt_Multiply(pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx]);
372 
373  // swap to the next temporary
374  BigInt *pSwap = pCurTemp;
375  pCurTemp = pNextTemp;
376  pNextTemp = pSwap;
377  }
378 
379  // advance to the next bit
380  ++tableIdx;
381  exponent >>= 1;
382  }
383 
384  // output the result
385  *pResult = *pCurTemp;
386 }
387 
388 static void BigInt_MultiplyPow10(BigInt *pResult, const BigInt &in, uint32_t exponent)
389 {
390  // make sure the exponent is within the bounds of the lookup table data
391  assert(exponent < 512);
392 
393  // create two temporary values to reduce large integer copy operations
394  BigInt temp1;
395  BigInt temp2;
396  BigInt *pCurTemp = &temp1;
397  BigInt *pNextTemp = &temp2;
398 
399  // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
400  uint32_t smallExponent = exponent & 0x7;
401  if (smallExponent != 0)
402  {
403  BigInt_Multiply(pCurTemp, in, g_PowerOf10_U32[smallExponent]);
404  }
405  else
406  {
407  *pCurTemp = in;
408  }
409 
410  // remove the low bits that we used for the 32-bit lookup table
411  exponent >>= 3;
412  uint32_t tableIdx = 0;
413 
414  // while there are remaining bits in the exponent to be processed
415  while (exponent != 0)
416  {
417  // if the current bit is set, multiply it with the corresponding power of 10
418  if (exponent & 1)
419  {
420  // multiply into the next temporary
421  BigInt_Multiply(pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx]);
422 
423  // swap to the next temporary
424  BigInt *pSwap = pCurTemp;
425  pCurTemp = pNextTemp;
426  pNextTemp = pSwap;
427  }
428 
429  // advance to the next bit
430  ++tableIdx;
431  exponent >>= 1;
432  }
433 
434  // output the result
435  *pResult = *pCurTemp;
436 }
437 
438 static inline void BigInt_Pow2(BigInt *pResult, uint32_t exponent)
439 {
440  uint32_t blockIdx = exponent / 32;
441  assert(blockIdx < c_BigInt_MaxBlocks);
442 
443  for (uint32_t i = 0; i <= blockIdx; ++i)
444  pResult->m_blocks[i] = 0;
445 
446  pResult->m_length = blockIdx + 1;
447 
448  uint32_t bitIdx = (exponent % 32);
449  pResult->m_blocks[blockIdx] |= (1 << bitIdx);
450 }
451 
452 static uint32_t BigInt_DivideWithRemainder_MaxQuotient9(BigInt *pDividend, const BigInt &divisor)
453 {
454  // Check that the divisor has been correctly shifted into range and that it is not
455  // smaller than the dividend in length.
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);
460 
461  // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already
462  // the remainder.
463  uint32_t length = divisor.m_length;
464  if (pDividend->m_length < divisor.m_length)
465  return 0;
466 
467  const uint32_t *pFinalDivisorBlock = divisor.m_blocks + length - 1;
468  uint32_t *pFinalDividendBlock = pDividend->m_blocks + length - 1;
469 
470  // Compute an estimated quotient based on the high block value. This will either match the actual quotient or
471  // undershoot by one.
472  uint32_t quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
473  assert(quotient <= 9);
474 
475  // Divide out the estimated quotient
476  if (quotient != 0)
477  {
478  // dividend = dividend - divisor*quotient
479  const uint32_t *pDivisorCur = divisor.m_blocks;
480  uint32_t *pDividendCur = pDividend->m_blocks;
481 
482  uint64_t borrow = 0;
483  uint64_t carry = 0;
484  do
485  {
486  uint64_t product = (uint64_t)*pDivisorCur * (uint64_t)quotient + carry;
487  carry = product >> 32;
488 
489  uint64_t difference = (uint64_t)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
490  borrow = (difference >> 32) & 1;
491 
492  *pDividendCur = difference & 0xFFFFFFFF;
493 
494  ++pDivisorCur;
495  ++pDividendCur;
496  } while (pDivisorCur <= pFinalDivisorBlock);
497 
498  // remove all leading zero blocks from dividend
499  while (length > 0 && pDividend->m_blocks[length - 1] == 0)
500  --length;
501 
502  pDividend->m_length = length;
503  }
504 
505  // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct,
506  // we increment the quotient and subtract one more divisor from the dividend.
507  if (BigInt_Compare(*pDividend, divisor) >= 0)
508  {
509  ++quotient;
510 
511  // dividend = dividend - divisor
512  const uint32_t *pDivisorCur = divisor.m_blocks;
513  uint32_t *pDividendCur = pDividend->m_blocks;
514 
515  uint64_t borrow = 0;
516  do
517  {
518  uint64_t difference = (uint64_t)*pDividendCur - (uint64_t)*pDivisorCur - borrow;
519  borrow = (difference >> 32) & 1;
520 
521  *pDividendCur = difference & 0xFFFFFFFF;
522 
523  ++pDivisorCur;
524  ++pDividendCur;
525  } while (pDivisorCur <= pFinalDivisorBlock);
526 
527  // remove all leading zero blocks from dividend
528  while (length > 0 && pDividend->m_blocks[length - 1] == 0)
529  --length;
530 
531  pDividend->m_length = length;
532  }
533 
534  return quotient;
535 }
536 
537 static void BigInt_ShiftLeft(BigInt *pResult, uint32_t shift)
538 {
539  assert(shift != 0);
540 
541  uint32_t shifboollocks = shift / 32;
542  uint32_t shifboolits = shift % 32;
543 
544  // process blocks high to low so that we can safely process in place
545  const uint32_t *pInBlocks = pResult->m_blocks;
546  int32_t inLength = pResult->m_length;
547  assert(inLength + shifboollocks < c_BigInt_MaxBlocks);
548 
549  // check if the shift is block aligned
550  if (shifboolits == 0)
551  {
552  // copy blcoks from high to low
553  for (uint32_t *pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shifboollocks;
554  pInCur >= pInBlocks;
555  --pInCur, --pOutCur)
556  {
557  *pOutCur = *pInCur;
558  }
559 
560  // zero the remaining low blocks
561  for (uint32_t i = 0; i < shifboollocks; ++i)
562  pResult->m_blocks[i] = 0;
563 
564  pResult->m_length += shifboollocks;
565  }
566  // else we need to shift partial blocks
567  else
568  {
569  int32_t inBlockIdx = inLength - 1;
570  uint32_t ouboollockIdx = inLength + shifboollocks;
571 
572  // set the length to hold the shifted blocks
573  assert(ouboollockIdx < c_BigInt_MaxBlocks);
574  pResult->m_length = ouboollockIdx + 1;
575 
576  // output the initial blocks
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)
582  {
583  pResult->m_blocks[ouboollockIdx] = highBits | lowBits;
584  highBits = block << shifboolits;
585 
586  --inBlockIdx;
587  --ouboollockIdx;
588 
589  block = pResult->m_blocks[inBlockIdx];
590  lowBits = block >> lowBitsShift;
591  }
592 
593  // output the final blocks
594  assert(ouboollockIdx == shifboollocks + 1);
595  pResult->m_blocks[ouboollockIdx] = highBits | lowBits;
596  pResult->m_blocks[ouboollockIdx - 1] = block << shifboolits;
597 
598  // zero the remaining low blocks
599  for (uint32_t i = 0; i < shifboollocks; ++i)
600  pResult->m_blocks[i] = 0;
601 
602  // check if the terminating block has no set bits
603  if (pResult->m_blocks[pResult->m_length - 1] == 0)
604  --pResult->m_length;
605  }
606 }
607 
608 uint32_t Dragon4(
609  const uint64_t mantissa, // value significand
610  const int32_t exponent, // value exponent in base 2
611  const uint32_t mantissaHighBitIdx, // index of the highest set mantissa bit
612  const bool hasUnequalMargins, // is the high margin twice as large as the low margin
613  const tCutoffMode cutoffMode, // how to determine output length
614  uint32_t cutoffNumber, // parameter to the selected cutoffMode
615  char *pOubooluffer, // buffer to output into
616  uint32_t bufferSize, // maximum characters that can be printed to pOubooluffer
617  int32_t *pOutExponent // the base 10 exponent of the first digit
618  )
619 {
620  char *pCurDigit = pOubooluffer;
621 
622  assert(bufferSize > 0);
623 
624  // if the mantissa is zero, the value is zero regardless of the exponent
625  if (mantissa == 0)
626  {
627  *pCurDigit = '0';
628  *pOutExponent = 0;
629  return 1;
630  }
631 
632  // compute the initial state in integral form such that
633  // value = scaledValue / scale
634  // marginLow = scaledMarginLow / scale
635  BigInt scale; // positive scale applied to value and margin such that they can be
636  // represented as whole numbers
637  BigInt scaledValue; // scale * mantissa
638  BigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its
639  // immediate lower value)
640 
641  // For normalized IEEE floating point values, each time the exponent is incremented the margin also
642  // doubles. That creates a subset of transition numbers where the high margin is twice the size of
643  // the low margin.
644  BigInt *pScaledMarginHigh;
645  BigInt optionalMarginHigh;
646 
647  if (hasUnequalMargins)
648  {
649  // if we have no fractional component
650  if (exponent > 0)
651  {
652  // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
653  // the input value in its whole number representation.
654  // 2) Apply an additional scale of 2 such that later comparisons against the margin values
655  // are simplified.
656  // 3) Set the margin value to the lowest mantissa bit's scale.
657 
658  // scaledValue = 2 * 2 * mantissa*2^exponent
659  scaledValue.SetUInt64(4 * mantissa);
660  BigInt_ShiftLeft(&scaledValue, exponent);
661 
662  // scale = 2 * 2 * 1
663  scale.SetUInt32(4);
664 
665  // scaledMarginLow = 2 * 2^(exponent-1)
666  BigInt_Pow2(&scaledMarginLow, exponent);
667 
668  // scaledMarginHigh = 2 * 2 * 2^(exponent-1)
669  BigInt_Pow2(&optionalMarginHigh, exponent + 1);
670  }
671  // else we have a fractional exponent
672  else
673  {
674  // In order to track the mantissa data as an integer, we store it as is with a large scale
675 
676  // scaledValue = 2 * 2 * mantissa
677  scaledValue.SetUInt64(4 * mantissa);
678 
679  // scale = 2 * 2 * 2^(-exponent)
680  BigInt_Pow2(&scale, -exponent + 2);
681 
682  // scaledMarginLow = 2 * 2^(-1)
683  scaledMarginLow.SetUInt32(1);
684 
685  // scaledMarginHigh = 2 * 2 * 2^(-1)
686  optionalMarginHigh.SetUInt32(2);
687  }
688 
689  // the high and low margins are different
690  pScaledMarginHigh = &optionalMarginHigh;
691  }
692  else
693  {
694  // if we have no fractional component
695  if (exponent > 0)
696  {
697  // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
698  // the input value in its whole number representation.
699  // 2) Apply an additional scale of 2 such that later comparisons against the margin values
700  // are simplified.
701  // 3) Set the margin value to the lowest mantissa bit's scale.
702 
703  // scaledValue = 2 * mantissa*2^exponent
704  scaledValue.SetUInt64(2 * mantissa);
705  BigInt_ShiftLeft(&scaledValue, exponent);
706 
707  // scale = 2 * 1
708  scale.SetUInt32(2);
709 
710  // scaledMarginLow = 2 * 2^(exponent-1)
711  BigInt_Pow2(&scaledMarginLow, exponent);
712  }
713  // else we have a fractional exponent
714  else
715  {
716  // In order to track the mantissa data as an integer, we store it as is with a large scale
717 
718  // scaledValue = 2 * mantissa
719  scaledValue.SetUInt64(2 * mantissa);
720 
721  // scale = 2 * 2^(-exponent)
722  BigInt_Pow2(&scale, -exponent + 1);
723 
724  // scaledMarginLow = 2 * 2^(-1)
725  scaledMarginLow.SetUInt32(1);
726  }
727 
728  // the high and low margins are equal
729  pScaledMarginHigh = &scaledMarginLow;
730  }
731 
732  // Compute an estimate for digitExponent that will be correct or undershoot by one.
733  // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately"
734  // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
735  // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate
736  // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is
737  // less than one by a reasonable epsilon that will account for any floating point error.
738  //
739  // We want to set digitExponent to floor(log10(v)) + 1
740  // v = mantissa*2^exponent
741  // log2(v) = log2(mantissa) + exponent;
742  // log10(v) = log2(v) * log10(2)
743  // floor(log2(v)) = mantissaHighBitIdx + exponent;
744  // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v)
745  // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2)
746  // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1
747  const double log10_2 = 0.30102999566398119521373889472449;
748  int32_t digitExponent = (int32_t)(ceil(double((int32_t)mantissaHighBitIdx + exponent) * log10_2 - 0.69));
749 
750  // if the digit exponent is smaller than the smallest desired digit for fractional cutoff,
751  // pull the digit back into legal range at which point we will round to the appropriate value.
752  // Note that while our value for digitExponent is still an estimate, this is safe because it
753  // only increases the number. This will either correct digitExponent to an accurate value or it
754  // will clamp it above the accurate value.
755  if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(int32_t)cutoffNumber)
756  {
757  digitExponent = -(int32_t)cutoffNumber + 1;
758  }
759 
760  // Divide value by 10^digitExponent.
761  if (digitExponent > 0)
762  {
763  // The exponent is positive creating a division so we multiply up the scale.
764  BigInt temp;
765  BigInt_MultiplyPow10(&temp, scale, digitExponent);
766  scale = temp;
767  }
768  else if (digitExponent < 0)
769  {
770  // The exponent is negative creating a multiplication so we multiply up the scaledValue,
771  // scaledMarginLow and scaledMarginHigh.
772  BigInt pow10;
773  BigInt_Pow10(&pow10, -digitExponent);
774 
775  BigInt temp;
776  BigInt_Multiply(&temp, scaledValue, pow10);
777  scaledValue = temp;
778 
779  BigInt_Multiply(&temp, scaledMarginLow, pow10);
780  scaledMarginLow = temp;
781 
782  if (pScaledMarginHigh != &scaledMarginLow)
783  BigInt_Multiply2(pScaledMarginHigh, scaledMarginLow);
784  }
785 
786  // If (value >= 1), our estimate for digitExponent was too low
787  if (BigInt_Compare(scaledValue, scale) >= 0)
788  {
789  // The exponent estimate was incorrect.
790  // Increment the exponent and don't perform the premultiply needed
791  // for the first loop iteration.
792  digitExponent = digitExponent + 1;
793  }
794  else
795  {
796  // The exponent estimate was correct.
797  // Multiply larger by the output base to prepare for the first loop iteration.
798  BigInt_Multiply10(&scaledValue);
799  BigInt_Multiply10(&scaledMarginLow);
800  if (pScaledMarginHigh != &scaledMarginLow)
801  BigInt_Multiply2(pScaledMarginHigh, scaledMarginLow);
802  }
803 
804  // Compute the cutoff exponent (the exponent of the final digit to print).
805  // Default to the maximum size of the output buffer.
806  int32_t cutoffExponent = digitExponent - bufferSize;
807  switch (cutoffMode)
808  {
809  // print digits until we pass the accuracy margin limits or buffer size
810  case CutoffMode_Unique:
811  break;
812 
813  // print cutoffNumber of digits or until we reach the buffer size
815  {
816  int32_t desiredCutoffExponent = digitExponent - (int32_t)cutoffNumber;
817  if (desiredCutoffExponent > cutoffExponent)
818  cutoffExponent = desiredCutoffExponent;
819  }
820  break;
821 
822  // print cutoffNumber digits past the decimal point or until we reach the buffer size
824  {
825  int32_t desiredCutoffExponent = -(int32_t)cutoffNumber;
826  if (desiredCutoffExponent > cutoffExponent)
827  cutoffExponent = desiredCutoffExponent;
828  }
829  break;
830  }
831 
832  // Output the exponent of the first digit we will print
833  *pOutExponent = digitExponent - 1;
834 
835  // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(),
836  // we need to scale up our values such that the highest block of the denominator
837  // is greater than or equal to 8. We also need to guarantee that the numerator
838  // can never have a length greater than the denominator after each loop iteration.
839  // This requires the highest block of the denominator to be less than or equal to
840  // 429496729 which is the highest number that can be multiplied by 10 without
841  // overflowing to a new block.
842  assert(scale.GetLength() > 0);
843  uint32_t hiBlock = scale.Geboollock(scale.GetLength() - 1);
844  if (hiBlock < 8 || hiBlock > 429496729)
845  {
846  // Perform a bit shift on all values to get the highest block of the denominator into
847  // the range [8,429496729]. We are more likely to make accurate quotient estimations
848  // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so
849  // we shift the denominator to place the highest bit at index 27 of the highest block.
850  // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means
851  // that all values with a highest bit at index 27 are within range.
852  uint32_t hiBlockLog2 = log2i(hiBlock);
853  assert(hiBlockLog2 < 3 || hiBlockLog2 > 27);
854  uint32_t shift = (32 + 27 - hiBlockLog2) % 32;
855 
856  BigInt_ShiftLeft(&scale, shift);
857  BigInt_ShiftLeft(&scaledValue, shift);
858  BigInt_ShiftLeft(&scaledMarginLow, shift);
859  if (pScaledMarginHigh != &scaledMarginLow)
860  BigInt_Multiply2(pScaledMarginHigh, scaledMarginLow);
861  }
862 
863  // These values are used to inspect why the print loop terminated so we can properly
864  // round the final digit.
865  bool low; // did the value get within marginLow distance from zero
866  bool high; // did the value get within marginHigh distance from one
867  uint32_t outputDigit; // current digit being output
868 
869  if (cutoffMode == CutoffMode_Unique)
870  {
871  // For the unique cutoff mode, we will try to print until we have reached a level of
872  // precision that uniquely distinguishes this value from its neighbors. If we run
873  // out of space in the output buffer, we terminate early.
874  for (;;)
875  {
876  digitExponent = digitExponent - 1;
877 
878  // divide out the scale to extract the digit
879  outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
880  assert(outputDigit < 10);
881 
882  // update the high end of the value
883  BigInt scaledValueHigh;
884  BigInt_Add(&scaledValueHigh, scaledValue, *pScaledMarginHigh);
885 
886  // stop looping if we are far enough away from our neighboring values
887  // or if we have reached the cutoff digit
888  low = BigInt_Compare(scaledValue, scaledMarginLow) < 0;
889  high = BigInt_Compare(scaledValueHigh, scale) > 0;
890  if (low | high | (digitExponent == cutoffExponent))
891  break;
892 
893  // store the output digit
894  *pCurDigit = (char)('0' + outputDigit);
895  ++pCurDigit;
896 
897  // multiply larger by the output base
898  BigInt_Multiply10(&scaledValue);
899  BigInt_Multiply10(&scaledMarginLow);
900  if (pScaledMarginHigh != &scaledMarginLow)
901  BigInt_Multiply2(pScaledMarginHigh, scaledMarginLow);
902  }
903  }
904  else
905  {
906  // For length based cutoff modes, we will try to print until we
907  // have exhausted all precision (i.e. all remaining digits are zeros) or
908  // until we reach the desired cutoff digit.
909  low = false;
910  high = false;
911 
912  for (;;)
913  {
914  digitExponent = digitExponent - 1;
915 
916  // divide out the scale to extract the digit
917  outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
918  assert(outputDigit < 10);
919 
920  if (scaledValue.IsZero() | (digitExponent == cutoffExponent))
921  break;
922 
923  // store the output digit
924  *pCurDigit = (char)('0' + outputDigit);
925  ++pCurDigit;
926 
927  // multiply larger by the output base
928  BigInt_Multiply10(&scaledValue);
929  }
930  }
931 
932  // round off the final digit
933  // default to rounding down if value got too close to 0
934  bool roundDown = low;
935 
936  // if it is legal to round up and down
937  if (low == high)
938  {
939  // round to the closest digit by comparing value with 0.5. To do this we need to convert
940  // the inequality to large integer values.
941  // compare( value, 0.5 )
942  // compare( scale * value, scale * 0.5 )
943  // compare( 2 * scale * value, scale )
944  BigInt_Multiply2(&scaledValue);
945  int32_t compare = BigInt_Compare(scaledValue, scale);
946  roundDown = compare < 0;
947 
948  // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules)
949  if (compare == 0)
950  roundDown = (outputDigit & 1) == 0;
951  }
952 
953  // print the rounded digit
954  if (roundDown)
955  {
956  *pCurDigit = (char)('0' + outputDigit);
957  ++pCurDigit;
958  }
959  else
960  {
961  // handle rounding up
962  if (outputDigit == 9)
963  {
964  // find the first non-nine prior digit
965  for (;;)
966  {
967  // if we are at the first digit
968  if (pCurDigit == pOubooluffer)
969  {
970  // output 1 at the next highest exponent
971  *pCurDigit = '1';
972  ++pCurDigit;
973  *pOutExponent += 1;
974  break;
975  }
976 
977  --pCurDigit;
978  if (*pCurDigit != '9')
979  {
980  // increment the digit
981  *pCurDigit += 1;
982  ++pCurDigit;
983  break;
984  }
985  }
986  }
987  else
988  {
989  // values in the range [0,8] can perform a simple round up
990  *pCurDigit = (char)('0' + outputDigit + 1);
991  ++pCurDigit;
992  }
993  }
994 
995  // return the number of digits output
996  uint32_t outputLen = (uint32_t)(pCurDigit - pOubooluffer);
997  assert(outputLen <= bufferSize);
998  return outputLen;
999 }
#define assert(x)
Definition: amath.h:124
static void BigInt_ShiftLeft(BigInt *pResult, uint32_t shift)
Definition: bigint.cpp:537
static void BigInt_Multiply10(BigInt *pResult)
Definition: bigint.cpp:285
static void BigInt_Multiply2(BigInt *pResult)
Definition: bigint.cpp:262
double ceil(double x)
Ceiling function.
Definition: ceil.c:63
static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
Definition: bigint.cpp:142
Definition: bigint.h:61
uint32_t Geboollock(uint32_t idx) const
Definition: bigint.h:78
uint32_t GetLength() const
Definition: bigint.h:77
uint32_t m_blocks[c_BigInt_MaxBlocks]
Definition: bigint.h:117
static void BigInt_Add(BigInt *pResult, const BigInt &lhs, const BigInt &rhs)
Definition: bigint.cpp:79
void SetUInt32(uint32_t val)
Definition: bigint.h:101
unsigned int log2i(unsigned int x)
BigInt & operator=(const BigInt &rhs)
Definition: bigint.h:63
static void BigInt_MultiplyPow10(BigInt *pResult, const BigInt &in, uint32_t exponent)
Definition: bigint.cpp:388
static int32_t BigInt_Compare(const BigInt &lhs, const BigInt &rhs)
Definition: bigint.cpp:57
static void BigInt_Multiply2(BigInt *pResult, const BigInt &in)
Definition: bigint.cpp:234
static void BigInt_Multiply(BigInt *pResult, const BigInt &lhs, uint32_t rhs)
Definition: bigint.cpp:206
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)
Definition: bigint.cpp:608
static void BigInt_Pow10(BigInt *pResult, uint32_t exponent)
Definition: bigint.cpp:345
static uint32_t g_PowerOf10_U32[]
Definition: bigint.cpp:308
uint32_t m_length
Definition: bigint.h:116
static BigInt g_PowerOf10_Big[]
Definition: bigint.cpp:320
void SetUInt64(uint64_t val)
Definition: bigint.h:82
tCutoffMode
Definition: bigint.h:120
bool IsZero() const
Definition: bigint.h:80
static void BigInt_Pow2(BigInt *pResult, uint32_t exponent)
Definition: bigint.cpp:438
static uint32_t BigInt_DivideWithRemainder_MaxQuotient9(BigInt *pDividend, const BigInt &divisor)
Definition: bigint.cpp:452