| 627 | }; |
| 628 | |
| 629 | void fxBigintToString(txMachine* the, txSlot* slot, txU4 radix) |
| 630 | { |
| 631 | static const char gxDigits[] ICACHE_FLASH_ATTR = "0123456789abcdefghijklmnopqrstuvwxyz"; |
| 632 | txSize length, offset; |
| 633 | txSlot* result; |
| 634 | txSlot* stack; |
| 635 | if (0 == radix) radix = 10; |
| 636 | const BaseChunk32 *bc = base_chunks32 + (radix - 2); |
| 637 | |
| 638 | if (mxBigIntIsNaN(&slot->value.bigint)) { |
| 639 | fxStringX(the, slot, "NaN"); |
| 640 | return; |
| 641 | } |
| 642 | mxBigInt_meter(slot->value.bigint.size); |
| 643 | |
| 644 | mxPushUndefined(); |
| 645 | result = the->stack; |
| 646 | |
| 647 | mxPushSlot(slot); |
| 648 | fxBigInt_dup(the, &the->stack->value.bigint); |
| 649 | stack = the->stack; |
| 650 | |
| 651 | length = 1 + bc->k + (txSize)c_ceil((txNumber)(stack->value.bigint.size + 1) * 32 * c_log(2) / c_log(radix)); |
| 652 | if (stack->value.bigint.sign) |
| 653 | length++; |
| 654 | offset = length; |
| 655 | result->value.string = fxNewChunk(the, length); |
| 656 | result->kind = XS_STRING_KIND; |
| 657 | |
| 658 | result->value.string[--offset] = 0; |
| 659 | int32_t nonZeroWords = stack->value.bigint.size; |
| 660 | do { |
| 661 | uint64_t carry = 0; |
| 662 | for (uint32_t i = nonZeroWords - 1, count = nonZeroWords, base_to_k = bc->base_to_k; count > 0; --count) { |
| 663 | carry = (carry << 32) | stack->value.bigint.data[i]; |
| 664 | stack->value.bigint.data[i--] = (uint32_t)(carry / base_to_k); |
| 665 | carry %= base_to_k; |
| 666 | } |
| 667 | uint32_t remainder = (uint32_t)carry, k = bc->k; |
| 668 | do { |
| 669 | result->value.string[--offset] = c_read8(gxDigits + (remainder % radix)); |
| 670 | remainder /= radix; |
| 671 | } while (--k); |
| 672 | |
| 673 | while (nonZeroWords && (0 == stack->value.bigint.data[nonZeroWords - 1])) |
| 674 | nonZeroWords -= 1; |
| 675 | } while (nonZeroWords); |
| 676 | |
| 677 | while (('0' == result->value.string[offset]) && result->value.string[offset + 1]) |
| 678 | offset++; |
| 679 | |
| 680 | if (stack->value.bigint.sign) |
| 681 | result->value.string[--offset] = '-'; |
| 682 | c_memmove(result->value.string, result->value.string + offset, length - offset); |
| 683 | |
| 684 | mxPop(); |
| 685 | mxPop(); |
| 686 | mxPullSlot(slot); |
no test coverage detected