From f289f8ae3ab3e76287597722c52cd8cfcfc694ad Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Wed, 6 Jan 2021 10:25:45 +0900 Subject: [ruby/bigdecimal] Optimize the conversion from small Bignum https://github.com/ruby/bigdecimal/commit/4792a917d8 --- ext/bigdecimal/bigdecimal.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'ext/bigdecimal') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index b4f71142e8..a912908664 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2763,8 +2763,32 @@ rb_int64_convert_to_BigDecimal(int64_t ival, size_t digs, int raise_exception) static VALUE rb_big_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_exception) { - Real *vp = GetVpValue(val, 1); - return check_exception(vp->obj); + assert(RB_TYPE_P(val, T_BIGNUM)); + + size_t size = rb_absint_size(val, NULL); + int sign = rb_big_cmp(val, INT2FIX(0)); + if (size <= sizeof(long)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LONG(val), digs, raise_exception); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULONG(val), digs, raise_exception); + } + } +#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG < SIZEOF_LONG_LONG + else if (size <= sizeof(LONG_LONG)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LL(val), digs, raise_exception); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULL(val), digs, raise_exception); + } + } +#endif + else { + Real *vp = GetVpValue(val, 1); + return check_exception(vp->obj); + } } static VALUE -- cgit v1.2.3