Exemplo n.º 1
0
inline static VALUE
f_gcd(VALUE x, VALUE y)
{
    VALUE z;

    if (FIXNUM_P(x) && FIXNUM_P(y))
	return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));

    if (f_negative_p(x))
	x = f_negate(x);
    if (f_negative_p(y))
	y = f_negate(y);

    if (f_zero_p(x))
	return y;
    if (f_zero_p(y))
	return x;

    for (;;) {
	if (FIXNUM_P(x)) {
	    if (FIX2LONG(x) == 0)
		return y;
	    if (FIXNUM_P(y))
		return LONG2NUM(i_gcd(FIX2LONG(x), FIX2LONG(y)));
	}
	z = x;
	x = f_mod(y, x);
	y = z;
    }
    /* NOTREACHED */
}
Exemplo n.º 2
0
inline static VALUE
f_rational_new_bang2(VALUE klass, VALUE x, VALUE y)
{
    assert(!f_negative_p(y));
    assert(!f_zero_p(y));
    return nurat_s_new_internal(klass, x, y);
}
Exemplo n.º 3
0
/*
 * call-seq:
 *    rat.to_i  ->  integer
 *
 * Returns the truncated value as an integer.
 *
 * Equivalent to
 *    rat.truncate.
 *
 * For example:
 *
 *    Rational(2, 3).to_i   #=> 0
 *    Rational(3).to_i      #=> 3
 *    Rational(300.6).to_i  #=> 300
 *    Rational(98,71).to_i  #=> 1
 *    Rational(-30,2).to_i  #=> -15
 */
static VALUE
nurat_truncate(VALUE self, SEL sel)
{
    get_dat1(self);
    if (f_negative_p(dat->num))
	return f_negate(f_idiv(f_negate(dat->num), dat->den));
    return f_idiv(dat->num, dat->den);
}
Exemplo n.º 4
0
static VALUE
nurat_abs(VALUE self)
{
    if (!f_negative_p(self))
	return self;
    else
	return f_negate(self);
}
Exemplo n.º 5
0
inline static VALUE
f_signbit(VALUE x)
{
    if (RB_TYPE_P(x, T_FLOAT)) {
        double f = RFLOAT_VALUE(x);
        return f_boolcast(!isnan(f) && signbit(f));
    }
    return f_negative_p(x);
}
Exemplo n.º 6
0
static VALUE
nurat_to_f(VALUE self)
{
    VALUE num, den;
    int minus = 0;
    long nl, dl, ml, ne, de;
    int e;
    double f;

    {
	get_dat1(self);

	if (f_zero_p(dat->num))
	    return rb_float_new(0.0);

	num = dat->num;
	den = dat->den;
    }

    if (f_negative_p(num)) {
	num = f_negate(num);
	minus = 1;
    }

    nl = i_ilog2(num);
    dl = i_ilog2(den);
    ml = (long)(log(DBL_MAX) / log(2.0) - 1); /* should be a static */

    ne = 0;
    if (nl > ml) {
	ne = nl - ml;
	num = f_rshift(num, LONG2NUM(ne));
    }

    de = 0;
    if (dl > ml) {
	de = dl - ml;
	den = f_rshift(den, LONG2NUM(de));
    }

    e = (int)(ne - de);

    if ((e > DBL_MAX_EXP) || (e < DBL_MIN_EXP)) {
	rb_warning("%s out of Float range", rb_obj_classname(self));
	return rb_float_new(e > 0 ? HUGE_VAL : 0.0);
    }

    f = NUM2DBL(num) / NUM2DBL(den);
    if (minus)
	f = -f;
    f = ldexp(f, e);

    if (isinf(f) || isnan(f))
	rb_warning("%s out of Float range", rb_obj_classname(self));

    return rb_float_new(f);
}
Exemplo n.º 7
0
inline static VALUE
f_signbit(VALUE x)
{
    switch (TYPE(x)) {
      case T_FLOAT: {
	double f = RFLOAT_VALUE(x);
	return f_boolcast(!isnan(f) && signbit(f));
      }
    }
    return f_negative_p(x);
}
Exemplo n.º 8
0
inline static VALUE
f_signbit(VALUE x)
{
#if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun) && \
    !defined(signbit)
    extern int signbit(double);
#endif
    if (RB_TYPE_P(x, T_FLOAT)) {
	double f = RFLOAT_VALUE(x);
	return f_boolcast(!isnan(f) && signbit(f));
    }
    return f_negative_p(x);
}
Exemplo n.º 9
0
static VALUE
nurat_round(VALUE self)
{
    get_dat1(self);

    if (f_negative_p(dat->num)) {
	VALUE num, den;

	num = f_negate(dat->num);
	num = f_add(f_mul(num, TWO), dat->den);
	den = f_mul(dat->den, TWO);
	return f_negate(f_idiv(num, den));
    }
    else {
	VALUE num = f_add(f_mul(dat->num, TWO), dat->den);
	VALUE den = f_mul(dat->den, TWO);
	return f_idiv(num, den);
    }
}
Exemplo n.º 10
0
static VALUE
m_sqrt(VALUE x)
{
    if (f_real_p(x)) {
	if (f_positive_p(x))
	    return m_sqrt_bang(x);
	return f_complex_new2(rb_cComplex, ZERO, m_sqrt_bang(f_negate(x)));
    }
    else {
	get_dat1(x);

	if (f_negative_p(dat->imag))
	    return f_conj(m_sqrt(f_conj(x)));
	else {
	    VALUE a = f_abs(x);
	    return f_complex_new2(rb_cComplex,
				  m_sqrt_bang(f_div(f_add(a, dat->real), TWO)),
				  m_sqrt_bang(f_div(f_sub(a, dat->real), TWO)));
	}
    }
}
Exemplo n.º 11
0
inline static VALUE
f_muldiv(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
{
    VALUE num, den;

    if (k == '/') {
	VALUE t;

	if (f_negative_p(bnum)) {
	    anum = f_negate(anum);
	    bnum = f_negate(bnum);
	}
	t = bnum;
	bnum = bden;
	bden = t;
    }

    if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
	FIXNUM_P(bnum) && FIXNUM_P(bden)) {
	long an = FIX2LONG(anum);
	long ad = FIX2LONG(aden);
	long bn = FIX2LONG(bnum);
	long bd = FIX2LONG(bden);
	long g1 = i_gcd(an, bd);
	long g2 = i_gcd(ad, bn);

	num = f_imul(an / g1, bn / g2);
	den = f_imul(ad / g2, bd / g1);
    }
    else {
	VALUE g1 = f_gcd(anum, bden);
	VALUE g2 = f_gcd(aden, bnum);

	num = f_mul(f_idiv(anum, g1), f_idiv(bnum, g2));
	den = f_mul(f_idiv(aden, g2), f_idiv(bden, g1));
    }
    return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
}
Exemplo n.º 12
0
static VALUE
nurat_round(VALUE self, SEL sel)
{
    VALUE num, den, neg;

    get_dat1(self);

    num = dat->num;
    den = dat->den;
    neg = f_negative_p(num);

    if (neg)
	num = f_negate(num);

    num = f_add(f_mul(num, TWO), den);
    den = f_mul(den, TWO);
    num = f_idiv(num, den);

    if (neg)
	num = f_negate(num);

    return num;
}
Exemplo n.º 13
0
inline static VALUE
f_signbit(VALUE x)
{
    switch (TYPE(x)) {
      case T_FLOAT:
#ifdef HAVE_SIGNBIT
      {
	  double f = RFLOAT_VALUE(x);
	  return f_boolcast(!isnan(f) && signbit(f));
      }
#else
      {
	  char s[2];
	  double f = RFLOAT_VALUE(x);

	  if (isnan(f)) return Qfalse;
	  (void)snprintf(s, sizeof s, "%.0f", f);
	  return f_boolcast(s[0] == '-');
      }
#endif
    }
    return f_negative_p(x);
}