From f830ace8a831a954db7a6aae280a530651a5b58a Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 13 Aug 2015 05:36:33 +0000 Subject: object.c: rb_num_to_dbl * object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++ internal.h | 47 +++++++++------ math.c | 47 +-------------- object.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 189 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a6fcffa06..332821c81b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Aug 13 14:36:31 2015 Nobuyoshi Nakada + + * object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c. + Thu Aug 13 09:01:25 2015 Eric Wong * load.c (features_index_add): avoid repeat calculation diff --git a/internal.h b/internal.h index 59526c8ec7..a1eadfa074 100644 --- a/internal.h +++ b/internal.h @@ -903,31 +903,41 @@ VALUE rb_dbl_hash(double d); #endif static inline double -rb_float_value_inline(VALUE v) +rb_float_flonum_value(VALUE v) { #if USE_FLONUM - if (FLONUM_P(v)) { - if (v != (VALUE)0x8000000000000002) { /* LIKELY */ - union { - double d; - VALUE v; - } t; - - VALUE b63 = (v >> 63); - /* e: xx1... -> 011... */ - /* xx0... -> 100... */ - /* ^b63 */ - t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3); - return t.d; - } - else { - return 0.0; - } + if (v != (VALUE)0x8000000000000002) { /* LIKELY */ + union { + double d; + VALUE v; + } t; + + VALUE b63 = (v >> 63); + /* e: xx1... -> 011... */ + /* xx0... -> 100... */ + /* ^b63 */ + t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~0x03), 3); + return t.d; } #endif + return 0.0; +} + +static inline double +rb_float_noflonum_value(VALUE v) +{ return ((struct RFloat *)v)->float_value; } +static inline double +rb_float_value_inline(VALUE v) +{ + if (FLONUM_P(v)) { + return rb_float_flonum_value(v); + } + return rb_float_noflonum_value(v); +} + static inline VALUE rb_float_new_inline(double d) { @@ -965,6 +975,7 @@ rb_float_new_inline(double d) void rb_obj_copy_ivar(VALUE dest, VALUE obj); VALUE rb_obj_equal(VALUE obj1, VALUE obj2); VALUE rb_class_search_ancestor(VALUE klass, VALUE super); +double rb_num_to_dbl(VALUE val); struct RBasicRaw { VALUE flags; diff --git a/math.c b/math.c index 134d937358..591d6ae2f2 100644 --- a/math.c +++ b/math.c @@ -21,54 +21,10 @@ #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM) -static ID id_to_f; - VALUE rb_mMath; VALUE rb_eMathDomainError; -static inline int -basic_to_f_p(VALUE klass) -{ - return rb_method_basic_definition_p(klass, id_to_f); -} - -#define fix2dbl_without_to_f(x) (double)FIX2LONG(x) -#define big2dbl_without_to_f(x) rb_big2dbl(x) -#define int2dbl_without_to_f(x) (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x)) -#define rat2dbl_without_to_f(x) \ - (int2dbl_without_to_f(rb_rational_num(x)) / \ - int2dbl_without_to_f(rb_rational_den(x))) - -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 fix2dbl_without_to_f(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 big2dbl_without_to_f(num); - break; - case T_RATIONAL: - if (basic_to_f_p(rb_cRational)) - return rat2dbl_without_to_f(num); - break; - } - } - return RFLOAT_VALUE(rb_to_float(num)); -} - -#define Get_Double(x) num2dbl_with_to_f(x) +#define Get_Double(x) rb_num_to_dbl(x) #define domain_error(msg) \ rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg) @@ -1024,6 +980,5 @@ InitVM_Math(void) void Init_Math(void) { - id_to_f = rb_intern_const("to_f"); InitVM(Math); } diff --git a/object.c b/object.c index 51355e1354..910fb4e5d1 100644 --- a/object.c +++ b/object.c @@ -2903,33 +2903,84 @@ rb_str_to_dbl(VALUE str, int badcheck) return ret; } +#define fix2dbl_without_to_f(x) (double)FIX2LONG(x) +#define big2dbl_without_to_f(x) rb_big2dbl(x) +#define int2dbl_without_to_f(x) \ + (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x)) +#define rat2dbl_without_to_f(x) \ + (int2dbl_without_to_f(rb_rational_num(x)) / \ + int2dbl_without_to_f(rb_rational_den(x))) + +#define special_const_to_float(val, pre, post) \ + switch (val) { \ + case Qnil: \ + rb_raise(rb_eTypeError, pre "nil" post); \ + case Qtrue: \ + rb_raise(rb_eTypeError, pre "true" post); \ + case Qfalse: \ + rb_raise(rb_eTypeError, pre "false" post); \ + } + +static inline void +conversion_to_float(VALUE val) +{ + special_const_to_float(val, "can't convert ", " into Float"); +} + +static inline void +implicit_conversion_to_float(VALUE val) +{ + special_const_to_float(val, "no implicit conversion to float from ", ""); +} + +static int +to_float(VALUE *valp) +{ + VALUE val = *valp; + if (SPECIAL_CONST_P(val)) { + if (FIXNUM_P(val)) { + *valp = DBL2NUM(fix2dbl_without_to_f(val)); + return T_FLOAT; + } + else if (FLONUM_P(val)) { + return T_FLOAT; + } + else { + conversion_to_float(val); + } + } + else { + int type = BUILTIN_TYPE(val); + switch (type) { + case T_FLOAT: + return T_FLOAT; + case T_BIGNUM: + *valp = DBL2NUM(big2dbl_without_to_f(val)); + return T_FLOAT; + case T_RATIONAL: + *valp = DBL2NUM(rat2dbl_without_to_f(val)); + return T_FLOAT; + case T_STRING: + return T_STRING; + } + } + return T_NONE; +} + VALUE rb_Float(VALUE val) { - switch (TYPE(val)) { - case T_FIXNUM: - return DBL2NUM((double)FIX2LONG(val)); - + switch (to_float(&val)) { case T_FLOAT: return val; - - case T_BIGNUM: - return DBL2NUM(rb_big2dbl(val)); - case T_STRING: return DBL2NUM(rb_str_to_dbl(val, TRUE)); - - case T_NIL: - rb_raise(rb_eTypeError, "can't convert nil into Float"); - break; - - default: - return rb_convert_type(val, T_FLOAT, "Float", "to_f"); } - - UNREACHABLE; + return rb_convert_type(val, T_FLOAT, "Float", "to_f"); } +FUNC_MINIMIZED(static VALUE rb_f_float(VALUE obj, VALUE arg)); + /* * call-seq: * Float(arg) -> float @@ -2948,20 +2999,26 @@ rb_f_float(VALUE obj, VALUE arg) return rb_Float(arg); } -VALUE -rb_to_float(VALUE val) +static VALUE +numeric_to_float(VALUE val) { - if (RB_TYPE_P(val, T_FLOAT)) return val; if (!rb_obj_is_kind_of(val, rb_cNumeric)) { - rb_raise(rb_eTypeError, "can't convert %s into Float", - NIL_P(val) ? "nil" : - val == Qtrue ? "true" : - val == Qfalse ? "false" : - rb_obj_classname(val)); + rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into Float", + rb_obj_class(val)); } return rb_convert_type(val, T_FLOAT, "Float", "to_f"); } +VALUE +rb_to_float(VALUE val) +{ + switch (to_float(&val)) { + case T_FLOAT: + return val; + } + return numeric_to_float(val); +} + VALUE rb_check_to_float(VALUE val) { @@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val) return rb_check_convert_type(val, T_FLOAT, "Float", "to_f"); } -double -rb_num2dbl(VALUE val) -{ - switch (TYPE(val)) { - case T_FLOAT: - return RFLOAT_VALUE(val); - - case T_STRING: - rb_raise(rb_eTypeError, "no implicit conversion to float from string"); - break; +static ID id_to_f; - case T_NIL: - rb_raise(rb_eTypeError, "no implicit conversion to float from nil"); - break; +static inline int +basic_to_f_p(VALUE klass) +{ + return rb_method_basic_definition_p(klass, id_to_f); +} - default: - break; +double +rb_num_to_dbl(VALUE val) +{ + if (SPECIAL_CONST_P(val)) { + if (FIXNUM_P(val)) { + if (basic_to_f_p(rb_cFixnum)) + return fix2dbl_without_to_f(val); + } + else if (FLONUM_P(val)) { + return rb_float_flonum_value(val); + } + else { + conversion_to_float(val); + } } + else { + switch (BUILTIN_TYPE(val)) { + case T_FLOAT: + return rb_float_noflonum_value(val); + case T_BIGNUM: + if (basic_to_f_p(rb_cBignum)) + return big2dbl_without_to_f(val); + break; + case T_RATIONAL: + if (basic_to_f_p(rb_cRational)) + return rat2dbl_without_to_f(val); + break; + } + } + val = numeric_to_float(val); + return RFLOAT_VALUE(val); +} - return RFLOAT_VALUE(rb_Float(val)); +double +rb_num2dbl(VALUE val) +{ + if (SPECIAL_CONST_P(val)) { + if (FIXNUM_P(val)) { + return fix2dbl_without_to_f(val); + } + else if (FLONUM_P(val)) { + return rb_float_flonum_value(val); + } + else { + implicit_conversion_to_float(val); + } + } + else { + switch (BUILTIN_TYPE(val)) { + case T_FLOAT: + return rb_float_noflonum_value(val); + case T_BIGNUM: + return big2dbl_without_to_f(val); + case T_RATIONAL: + return rat2dbl_without_to_f(val); + case T_STRING: + rb_raise(rb_eTypeError, "no implicit conversion to float from string"); + } + } + val = rb_convert_type(val, T_FLOAT, "Float", "to_f"); + return RFLOAT_VALUE(val); } VALUE @@ -3243,7 +3349,7 @@ rb_f_hash(VALUE obj, VALUE arg) */ void -Init_Object(void) +InitVM_Object(void) { Init_class_hierarchy(); @@ -3461,3 +3567,10 @@ Init_Object(void) */ rb_define_global_const("FALSE", Qfalse); } + +void +Init_Object(void) +{ + id_to_f = rb_intern_const("to_f"); + InitVM(Object); +} -- cgit v1.2.3