diff options
author | Kenta Murata <mrkn@mrkn.jp> | 2021-11-18 10:59:12 +0900 |
---|---|---|
committer | Kenta Murata <mrkn@mrkn.jp> | 2021-12-24 02:28:55 +0900 |
commit | 8ee8ac64239626a9adea4e02ba3f0c4be4895e36 (patch) | |
tree | 9403dfaf75cd9dac201707fccea691fb9a58e02a /ext/bigdecimal | |
parent | b2a74948b6fe60727235b80ab56b4c701c315aa3 (diff) | |
download | ruby-8ee8ac64239626a9adea4e02ba3f0c4be4895e36.tar.gz |
[ruby/bigdecimal] Fix trailing zeros handling in rb_uint64_convert_to_BigDecimal
Fix GH-192
https://github.com/ruby/bigdecimal/commit/eebc98b85a
Diffstat (limited to 'ext/bigdecimal')
-rw-r--r-- | ext/bigdecimal/bigdecimal.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 8a107386a4..7cec33b7c9 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2862,21 +2862,29 @@ rb_uint64_convert_to_BigDecimal(uint64_t uval, RB_UNUSED_VAR(size_t digs), int r } else { DECDIG buf[BIGDECIMAL_INT64_MAX_LENGTH] = {0,}; - size_t exp = 0, ntz = 0; - for (; uval > 0; ++exp) { - DECDIG r = uval % BASE; - if (r == 0) ++ntz; - buf[BIGDECIMAL_INT64_MAX_LENGTH - exp - 1] = r; + DECDIG r = uval % BASE; + size_t len = 0, ntz = 0; + if (r == 0) { + // Count and skip trailing zeros + for (; r == 0 && uval > 0; ++ntz) { + uval /= BASE; + r = uval % BASE; + } + } + for (; uval > 0; ++len) { + // Store digits + buf[BIGDECIMAL_INT64_MAX_LENGTH - len - 1] = r; uval /= BASE; + r = uval % BASE; } - const size_t len = exp - ntz; + const size_t exp = len + ntz; vp = VpAllocReal(len); vp->MaxPrec = len; vp->Prec = len; vp->exponent = exp; VpSetSign(vp, 1); - MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - exp, DECDIG, len); + MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - len, DECDIG, len); } return BigDecimal_wrap_struct(obj, vp); |