mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	rational.c: avoid needless object allocation with nurat_to_double
* rational.c (nurat_to_double): introduce to convert rational to double
  without object allocation.
* rational.c (rb_rational_plus, nurat_{sub,mul,to_f}): rewrite by using
  nurat_to_double.
* bignum.c (rb_big_fdiv_double): introduce to calculate fdiv and return
  the result as a double value.
* bignum.c (big_fdiv{,_int,_float}): change the return types for
  implementing rb_big_fdiv_double.
* bignum.c (rb_big_fdiv): rewrite by using rb_big_fdiv_double.
* numeric.c (rb_int_fdiv_double): introduce to calculate fdiv and return
  the result as a double value.
* numeric.c (fix_fdiv_double): rewrite from fix_fdiv to return the
  result as a double value.
* numeric.c (rb_int_fdiv): rewrite by using rb_int_fdiv_double.
* internal.h (rb_{big,int}_fdiv_double): exported.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56719 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
			
			
This commit is contained in:
		
							parent
							
								
									6feb1684f3
								
							
						
					
					
						commit
						06d701a1f0
					
				
					 4 changed files with 62 additions and 41 deletions
				
			
		
							
								
								
									
										28
									
								
								bignum.c
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								bignum.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6090,7 +6090,7 @@ big_shift(VALUE x, long n)
 | 
			
		|||
    return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
static double
 | 
			
		||||
big_fdiv(VALUE x, VALUE y, long ey)
 | 
			
		||||
{
 | 
			
		||||
#define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
 | 
			
		||||
| 
						 | 
				
			
			@ -6108,14 +6108,14 @@ big_fdiv(VALUE x, VALUE y, long ey)
 | 
			
		|||
#if SIZEOF_LONG > SIZEOF_INT
 | 
			
		||||
    {
 | 
			
		||||
	/* Visual C++ can't be here */
 | 
			
		||||
	if (l > INT_MAX) return DBL2NUM(INFINITY);
 | 
			
		||||
	if (l < INT_MIN) return DBL2NUM(0.0);
 | 
			
		||||
	if (l > INT_MAX) return INFINITY;
 | 
			
		||||
	if (l < INT_MIN) return 0.0;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return DBL2NUM(ldexp(big2dbl(z), (int)l));
 | 
			
		||||
    return ldexp(big2dbl(z), (int)l);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
static double
 | 
			
		||||
big_fdiv_int(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    long l, ey;
 | 
			
		||||
| 
						 | 
				
			
			@ -6127,7 +6127,7 @@ big_fdiv_int(VALUE x, VALUE y)
 | 
			
		|||
    return big_fdiv(x, y, ey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
static double
 | 
			
		||||
big_fdiv_float(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
| 
						 | 
				
			
			@ -6135,8 +6135,8 @@ big_fdiv_float(VALUE x, VALUE y)
 | 
			
		|||
    return big_fdiv(x, y, i - DBL_MANT_DIG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_big_fdiv(VALUE x, VALUE y)
 | 
			
		||||
double
 | 
			
		||||
rb_big_fdiv_double(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    double dx, dy;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6154,14 +6154,20 @@ rb_big_fdiv(VALUE x, VALUE y)
 | 
			
		|||
    else if (RB_FLOAT_TYPE_P(y)) {
 | 
			
		||||
	dy = RFLOAT_VALUE(y);
 | 
			
		||||
	if (isnan(dy))
 | 
			
		||||
	    return y;
 | 
			
		||||
	    return dy;
 | 
			
		||||
	if (isinf(dx))
 | 
			
		||||
	    return big_fdiv_float(x, y);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
 | 
			
		||||
	return RFLOAT_VALUE(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
 | 
			
		||||
    }
 | 
			
		||||
    return DBL2NUM(dx / dy);
 | 
			
		||||
    return dx / dy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_big_fdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    return DBL2NUM(rb_big_fdiv_double(x, y));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -891,7 +891,7 @@ size_t rb_ary_memsize(VALUE);
 | 
			
		|||
 | 
			
		||||
/* bignum.c */
 | 
			
		||||
extern const char ruby_digitmap[];
 | 
			
		||||
VALUE rb_big_fdiv(VALUE x, VALUE y);
 | 
			
		||||
double rb_big_fdiv_double(VALUE x, VALUE y);
 | 
			
		||||
VALUE rb_big_uminus(VALUE x);
 | 
			
		||||
VALUE rb_big_hash(VALUE);
 | 
			
		||||
VALUE rb_big_odd_p(VALUE);
 | 
			
		||||
| 
						 | 
				
			
			@ -1170,7 +1170,7 @@ VALUE rb_dbl_hash(double d);
 | 
			
		|||
VALUE rb_fix_plus(VALUE x, VALUE y);
 | 
			
		||||
VALUE rb_int_ge(VALUE x, VALUE y);
 | 
			
		||||
enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
 | 
			
		||||
VALUE rb_int_fdiv(VALUE x, VALUE y);
 | 
			
		||||
double rb_int_fdiv_double(VALUE x, VALUE y);
 | 
			
		||||
 | 
			
		||||
#if USE_FLONUM
 | 
			
		||||
#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								numeric.c
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								numeric.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3549,6 +3549,35 @@ rb_int_mul(VALUE x, VALUE y)
 | 
			
		|||
    return rb_num_coerce_bin(x, y, '*');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double
 | 
			
		||||
fix_fdiv_double(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    if (FIXNUM_P(y)) {
 | 
			
		||||
        return (double)FIX2LONG(x) / (double)FIX2LONG(y);
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 | 
			
		||||
        return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(y, T_FLOAT)) {
 | 
			
		||||
        return (double)FIX2LONG(x) / RFLOAT_VALUE(y);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        return RFLOAT_VALUE(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double
 | 
			
		||||
rb_int_fdiv_double(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    if (FIXNUM_P(x)) {
 | 
			
		||||
        return fix_fdiv_double(x, y);
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(x, T_BIGNUM)) {
 | 
			
		||||
        return rb_big_fdiv_double(x, y);
 | 
			
		||||
    }
 | 
			
		||||
    return NAN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  Document-method: Integer#fdiv
 | 
			
		||||
 *  call-seq:
 | 
			
		||||
| 
						 | 
				
			
			@ -3564,31 +3593,11 @@ rb_int_mul(VALUE x, VALUE y)
 | 
			
		|||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
fix_fdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    if (FIXNUM_P(y)) {
 | 
			
		||||
	return DBL2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y));
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 | 
			
		||||
	return rb_big_fdiv(rb_int2big(FIX2LONG(x)), y);
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(y, T_FLOAT)) {
 | 
			
		||||
	return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y));
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_int_fdiv(VALUE x, VALUE y)
 | 
			
		||||
{
 | 
			
		||||
    if (FIXNUM_P(x)) {
 | 
			
		||||
	return fix_fdiv(x, y);
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(x, T_BIGNUM)) {
 | 
			
		||||
	return rb_big_fdiv(x, y);
 | 
			
		||||
    if (RB_INTEGER_TYPE_P(x)) {
 | 
			
		||||
        return DBL2NUM(rb_int_fdiv_double(x, y));
 | 
			
		||||
    }
 | 
			
		||||
    return Qnil;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								rational.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								rational.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -721,7 +721,7 @@ f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
 | 
			
		|||
    return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE nurat_to_f(VALUE self);
 | 
			
		||||
static double nurat_to_double(VALUE self);
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *    rat + numeric  ->  numeric
 | 
			
		||||
| 
						 | 
				
			
			@ -747,7 +747,7 @@ rb_rational_plus(VALUE self, VALUE other)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(other, T_FLOAT)) {
 | 
			
		||||
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) + RFLOAT_VALUE(other));
 | 
			
		||||
	return DBL2NUM(nurat_to_double(self) + RFLOAT_VALUE(other));
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(other, T_RATIONAL)) {
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -788,7 +788,7 @@ nurat_sub(VALUE self, VALUE other)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_FLOAT_TYPE_P(other)) {
 | 
			
		||||
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) - RFLOAT_VALUE(other));
 | 
			
		||||
	return DBL2NUM(nurat_to_double(self) - RFLOAT_VALUE(other));
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(other, T_RATIONAL)) {
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -868,7 +868,7 @@ nurat_mul(VALUE self, VALUE other)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_FLOAT_TYPE_P(other)) {
 | 
			
		||||
	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) * RFLOAT_VALUE(other));
 | 
			
		||||
	return DBL2NUM(nurat_to_double(self) * RFLOAT_VALUE(other));
 | 
			
		||||
    }
 | 
			
		||||
    else if (RB_TYPE_P(other, T_RATIONAL)) {
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1433,6 +1433,13 @@ nurat_round_n(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
    return f_round_common(argc, argv, self, round_func);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double
 | 
			
		||||
nurat_to_double(VALUE self)
 | 
			
		||||
{
 | 
			
		||||
    get_dat1(self);
 | 
			
		||||
    return rb_int_fdiv_double(dat->num, dat->den);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *    rat.to_f  ->  float
 | 
			
		||||
| 
						 | 
				
			
			@ -1447,8 +1454,7 @@ nurat_round_n(int argc, VALUE *argv, VALUE self)
 | 
			
		|||
static VALUE
 | 
			
		||||
nurat_to_f(VALUE self)
 | 
			
		||||
{
 | 
			
		||||
    get_dat1(self);
 | 
			
		||||
    return rb_int_fdiv(dat->num, dat->den);
 | 
			
		||||
    return DBL2NUM(nurat_to_double(self));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue