[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]