diff --git a/vm/bignum.cpp b/vm/bignum.cpp index f7c78d6e5b..2610be3a3c 100644 --- a/vm/bignum.cpp +++ b/vm/bignum.cpp @@ -270,8 +270,6 @@ bignum* factor_vm::bignum_remainder(bignum* numerator, bignum* denominator) { #define FOO_TO_BIGNUM(name, type, stype, utype) \ bignum* factor_vm::name##_to_bignum(type n) { \ int negative_p; \ - bignum_digit_type result_digits[BIGNUM_DIGITS_FOR(type)]; \ - bignum_digit_type* end_digits = result_digits; \ /* Special cases win when these small constants are cached. */ \ if (n == 0) \ return (BIGNUM_ZERO()); \ @@ -282,19 +280,22 @@ bignum* factor_vm::bignum_remainder(bignum* numerator, bignum* denominator) { { \ utype accumulator = \ ((negative_p = (n < (type) 0)) ? ((type)(-(stype) n)) : n); \ - do { \ - (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK); \ + if (accumulator < BIGNUM_RADIX) \ + { \ + bignum* result = allot_bignum(1, negative_p); \ + bignum_digit_type* scan = (BIGNUM_START_PTR(result)); \ + *scan = (accumulator & BIGNUM_DIGIT_MASK); \ + return (result); \ + } else { \ + BIGNUM_ASSERT(BIGNUM_DIGITS_FOR(type) == 2); \ + bignum* result = allot_bignum(2, negative_p); \ + bignum_digit_type* scan = (BIGNUM_START_PTR(result)); \ + (*scan++) = (accumulator & BIGNUM_DIGIT_MASK); \ accumulator >>= BIGNUM_DIGIT_LENGTH; \ - } while (accumulator != 0); \ - } \ - { \ - bignum* result = \ - (allot_bignum((end_digits - result_digits), negative_p)); \ - bignum_digit_type* scan_digits = result_digits; \ - bignum_digit_type* scan_result = (BIGNUM_START_PTR(result)); \ - while (scan_digits < end_digits) \ - (*scan_result++) = (*scan_digits++); \ - return (result); \ + *scan = (accumulator & BIGNUM_DIGIT_MASK); \ + BIGNUM_ASSERT((accumulator >> BIGNUM_DIGIT_LENGTH) == 0); \ + return (result); \ + } \ } \ }