mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									235e7738d6
								
							
						
					
					
						commit
						f830ace8a8
					
				
					 4 changed files with 188 additions and 105 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
Thu Aug 13 14:36:31 2015  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* 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@80x24.org>
 | 
			
		||||
 | 
			
		||||
	* load.c (features_index_add): avoid repeat calculation
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										45
									
								
								internal.h
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								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;
 | 
			
		||||
    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;
 | 
			
		||||
	}
 | 
			
		||||
	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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								math.c
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										197
									
								
								object.c
									
										
									
									
									
								
							
							
						
						
									
										197
									
								
								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,18 +2999,24 @@ rb_f_float(VALUE obj, VALUE arg)
 | 
			
		|||
    return rb_Float(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
numeric_to_float(VALUE val)
 | 
			
		||||
{
 | 
			
		||||
    if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
 | 
			
		||||
	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)
 | 
			
		||||
{
 | 
			
		||||
    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));
 | 
			
		||||
    switch (to_float(&val)) {
 | 
			
		||||
      case T_FLOAT:
 | 
			
		||||
	return val;
 | 
			
		||||
    }
 | 
			
		||||
    return rb_convert_type(val, T_FLOAT, "Float", "to_f");
 | 
			
		||||
    return numeric_to_float(val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -2972,26 +3029,75 @@ rb_check_to_float(VALUE val)
 | 
			
		|||
    return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ID id_to_f;
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
basic_to_f_p(VALUE klass)
 | 
			
		||||
{
 | 
			
		||||
    return rb_method_basic_definition_p(klass, id_to_f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
      case T_NIL:
 | 
			
		||||
	rb_raise(rb_eTypeError, "no implicit conversion to float from nil");
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
	break;
 | 
			
		||||
    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);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return RFLOAT_VALUE(rb_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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue