diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | math.c | 39 |
2 files changed, 37 insertions, 7 deletions
@@ -1,3 +1,8 @@ +Fri Jan 30 17:28:29 2015 gogotanaka <mail@tanakakazuki.com> + + * math.c (num2dbl_with_to_f): make faster when Bignum passed by + direct conversion using rb_big2dbl(). [Feature #10800] + Thu Jan 29 23:30:00 2015 Kenta Murata <mrkn@mrkn.jp> * ext/bigdecimal/bigdecimal.c (rb_rational_num): add fallback function @@ -26,13 +26,38 @@ static ID id_to_f; VALUE rb_mMath; VALUE rb_eMathDomainError; -#define fix_to_f_optimizable() rb_method_basic_definition_p(rb_cFixnum, id_to_f) -#define Get_Float(x) \ - ((RB_TYPE_P((x), T_FLOAT) ? (void)0 : ((x) = rb_to_float(x))), RFLOAT_VALUE(x)) -#define Get_Double(x) \ - (FIXNUM_P(x) && fix_to_f_optimizable() ? \ - (double)FIX2LONG(x) : \ - Get_Float(x)) +static inline int +basic_to_f_p(VALUE klass) +{ + return rb_method_basic_definition_p(klass, id_to_f); +} + +static inline double +num2dbl_with_to_f(VALUE num) +{ + if (SPECIAL_CONST_P(num)) { + if (FIXNUM_P(num)) { + if (basic_to_f_p(rb_cFixnum)) + return (double)FIX2LONG(num); + } + else if (FLONUM_P(num)) { + return RFLOAT_VALUE(num); + } + } + else { + switch (BUILTIN_TYPE(num)) { + case T_FLOAT: + return RFLOAT_VALUE(num); + case T_BIGNUM: + if (basic_to_f_p(rb_cBignum)) + return rb_big2dbl(num); + break; + } + } + return RFLOAT_VALUE(rb_to_float(num)); +} + +#define Get_Double(x) num2dbl_with_to_f(x) #define domain_error(msg) \ rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg) |