summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenta Murata <mrkn@mrkn.jp>2021-11-18 10:59:12 +0900
committerKenta Murata <mrkn@mrkn.jp>2021-12-24 02:28:55 +0900
commit8ee8ac64239626a9adea4e02ba3f0c4be4895e36 (patch)
tree9403dfaf75cd9dac201707fccea691fb9a58e02a
parentb2a74948b6fe60727235b80ab56b4c701c315aa3 (diff)
[ruby/bigdecimal] Fix trailing zeros handling in rb_uint64_convert_to_BigDecimal
Fix GH-192 https://github.com/ruby/bigdecimal/commit/eebc98b85a
-rw-r--r--ext/bigdecimal/bigdecimal.c22
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);