ruby-changes:39482
From: nobu <ko1@a...>
Date: Thu, 13 Aug 2015 14:36:50 +0900 (JST)
Subject: [ruby-changes:39482] nobu:r51563 (trunk): object.c: rb_num_to_dbl
nobu 2015-08-13 14:36:33 +0900 (Thu, 13 Aug 2015) New Revision: 51563 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51563 Log: object.c: rb_num_to_dbl * object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c. Modified files: trunk/ChangeLog trunk/internal.h trunk/math.c trunk/object.c Index: math.c =================================================================== --- math.c (revision 51562) +++ math.c (revision 51563) @@ -21,54 +21,10 @@ https://github.com/ruby/ruby/blob/trunk/math.c#L21 #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) https://github.com/ruby/ruby/blob/trunk/math.c#L980 void Init_Math(void) { - id_to_f = rb_intern_const("to_f"); InitVM(Math); } Index: ChangeLog =================================================================== --- ChangeLog (revision 51562) +++ ChangeLog (revision 51563) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Aug 13 14:36:31 2015 Nobuyoshi Nakada <nobu@r...> + + * object.c (rb_num_to_dbl): move from num2dbl_with_to_f in math.c. + Thu Aug 13 09:01:25 2015 Eric Wong <e@8...> * load.c (features_index_add): avoid repeat calculation Index: object.c =================================================================== --- object.c (revision 51562) +++ object.c (revision 51563) @@ -2903,33 +2903,84 @@ rb_str_to_dbl(VALUE str, int badcheck) https://github.com/ruby/ruby/blob/trunk/object.c#L2903 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,21 +2999,27 @@ rb_f_float(VALUE obj, VALUE arg) https://github.com/ruby/ruby/blob/trunk/object.c#L2999 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) { if (RB_TYPE_P(val, T_FLOAT)) return val; @@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val) https://github.com/ruby/ruby/blob/trunk/object.c#L3029 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) https://github.com/ruby/ruby/blob/trunk/object.c#L3349 */ void -Init_Object(void) +InitVM_Object(void) { Init_class_hierarchy(); @@ -3461,3 +3567,10 @@ Init_Object(void) https://github.com/ruby/ruby/blob/trunk/object.c#L3567 */ rb_define_global_const("FALSE", Qfalse); } + +void +Init_Object(void) +{ + id_to_f = rb_intern_const("to_f"); + InitVM(Object); +} Index: internal.h =================================================================== --- internal.h (revision 51562) +++ internal.h (revision 51563) @@ -903,31 +903,41 @@ VALUE rb_dbl_hash(double d); https://github.com/ruby/ruby/blob/trunk/internal.h#L903 #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) https://github.com/ruby/ruby/blob/trunk/internal.h#L975 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; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/