コード例 #1
0
ファイル: complex.c プロジェクト: DashYang/sim
/* :nodoc: */
static VALUE
nucomp_hash(VALUE self)
{
    st_index_t v, h[2];
    VALUE n;

    get_dat1(self);
    n = rb_hash(dat->real);
    h[0] = NUM2LONG(n);
    n = rb_hash(dat->imag);
    h[1] = NUM2LONG(n);
    v = rb_memhash(h, sizeof(h));
    return LONG2FIX(v);
}
コード例 #2
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
/* :nodoc: */
static VALUE
nurat_hash(VALUE self, SEL sel)
{
    long v, h[2];
    VALUE n;

    get_dat1(self);
    n = rb_hash(dat->num);
    h[0] = NUM2LONG(n);
    n = rb_hash(dat->den);
    h[1] = NUM2LONG(n);
    v = rb_memhash(h, sizeof(h));
    return LONG2FIX(v);
}
コード例 #3
0
ファイル: complex.c プロジェクト: DashYang/sim
/*
 * call-seq:
 *    cmp.numerator  ->  numeric
 *
 * Returns the numerator.
 *
 *        1   2       3+4i  <-  numerator
 *        - + -i  ->  ----
 *        2   3        6    <-  denominator
 *
 *    c = Complex('1/2+2/3i')  #=> ((1/2)+(2/3)*i)
 *    n = c.numerator          #=> (3+4i)
 *    d = c.denominator        #=> 6
 *    n / d                    #=> ((1/2)+(2/3)*i)
 *    Complex(Rational(n.real, d), Rational(n.imag, d))
 *                             #=> ((1/2)+(2/3)*i)
 * See denominator.
 */
static VALUE
nucomp_numerator(VALUE self)
{
    VALUE cd;

    get_dat1(self);

    cd = f_denominator(self);
    return f_complex_new2(CLASS_OF(self),
			  f_mul(f_numerator(dat->real),
				f_div(cd, f_denominator(dat->real))),
			  f_mul(f_numerator(dat->imag),
				f_div(cd, f_denominator(dat->imag))));
}
コード例 #4
0
ファイル: complex.c プロジェクト: DashYang/sim
static VALUE
m_sin(VALUE x)
{
    if (f_real_p(x))
	return m_sin_bang(x);
    {
	get_dat1(x);
	return f_complex_new2(rb_cComplex,
			      f_mul(m_sin_bang(dat->real),
				    m_cosh_bang(dat->imag)),
			      f_mul(m_cos_bang(dat->real),
				    m_sinh_bang(dat->imag)));
    }
}
コード例 #5
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
inline static VALUE
nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
{
#ifdef CANON
#define CL_CANON
#ifdef CL_CANON
    if (k_exact_zero_p(imag) && canonicalization)
	return real;
#else
    if (f_zero_p(imag) && canonicalization)
	return real;
#endif
#endif
    if (f_real_p(real) && f_real_p(imag))
	return nucomp_s_new_internal(klass, real, imag);
    else if (f_real_p(real)) {
	get_dat1(imag);

	return nucomp_s_new_internal(klass,
				     f_sub(real, dat->imag),
				     f_add(ZERO, dat->real));
    }
    else if (f_real_p(imag)) {
	get_dat1(real);

	return nucomp_s_new_internal(klass,
				     dat->real,
				     f_add(dat->imag, imag));
    }
    else {
	get_dat2(real, imag);

	return nucomp_s_new_internal(klass,
				     f_sub(adat->real, bdat->imag),
				     f_add(adat->imag, bdat->real));
    }
}
コード例 #6
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp == object  ->  true or false
 *
 * Returns true if cmp equals object numerically.
 *
 *    Complex(2, 3)  == Complex(2, 3)   #=> true
 *    Complex(5)     == 5               #=> true
 *    Complex(0)     == 0.0             #=> true
 *    Complex('1/3') == 0.33            #=> false
 *    Complex('1/2') == '1/2'           #=> false
 */
static VALUE
nucomp_eqeq_p(VALUE self, VALUE other)
{
    if (k_complex_p(other)) {
	get_dat2(self, other);

	return f_boolcast(f_eqeq_p(adat->real, bdat->real) &&
			  f_eqeq_p(adat->imag, bdat->imag));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_boolcast(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
    }
    return f_eqeq_p(other, self);
}
コード例 #7
0
ファイル: rational.c プロジェクト: Sophrinix/iphone-macruby
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);
    }
}
コード例 #8
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
static VALUE
f_format(VALUE self, VALUE (*func)(VALUE))
{
    VALUE s, impos;

    get_dat1(self);

    impos = f_tpositive_p(dat->imag);

    s = (*func)(dat->real);
    rb_str_cat2(s, !impos ? "-" : "+");

    rb_str_concat(s, (*func)(f_abs(dat->imag)));
    if (!rb_isdigit(RSTRING_PTR(s)[RSTRING_LEN(s) - 1]))
	rb_str_cat2(s, "*");
    rb_str_cat2(s, "i");

    return s;
}
コード例 #9
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.abs        ->  real
 *    cmp.magnitude  ->  real
 *
 * Returns the absolute part of its polar form.
 *
 *    Complex(-1).abs         #=> 1
 *    Complex(3.0, -4.0).abs  #=> 5.0
 */
static VALUE
nucomp_abs(VALUE self)
{
    get_dat1(self);

    if (f_zero_p(dat->real)) {
	VALUE a = f_abs(dat->imag);
	if (k_float_p(dat->real) && !k_float_p(dat->imag))
	    a = f_to_f(a);
	return a;
    }
    if (f_zero_p(dat->imag)) {
	VALUE a = f_abs(dat->real);
	if (!k_float_p(dat->real) && k_float_p(dat->imag))
	    a = f_to_f(a);
	return a;
    }
    return m_hypot(dat->real, dat->imag);
}
コード例 #10
0
ファイル: complex.c プロジェクト: Netfart/rhodes
static VALUE
nucomp_sub(VALUE self, VALUE other)
{
    if (k_complex_p(other)) {
	VALUE real, imag;

	get_dat2(self, other);

	real = f_sub(adat->real, bdat->real);
	imag = f_sub(adat->imag, bdat->imag);

	return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_complex_new2(CLASS_OF(self),
			      f_sub(dat->real, other), dat->imag);
    }
    return rb_num_coerce_bin(self, other, '-');
}
コード例 #11
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
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)));
	}
    }
}
コード例 #12
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
inline static VALUE
f_addsub(VALUE self, VALUE other,
	 VALUE (*func)(VALUE, VALUE), ID id)
{
    if (k_complex_p(other)) {
	VALUE real, imag;

	get_dat2(self, other);

	real = (*func)(adat->real, bdat->real);
	imag = (*func)(adat->imag, bdat->imag);

	return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_complex_new2(CLASS_OF(self),
			      (*func)(dat->real, other), dat->imag);
    }
    return rb_num_coerce_bin(self, other, id);
}
コード例 #13
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
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;
}
コード例 #14
0
ファイル: rational.c プロジェクト: Sophrinix/iphone-macruby
static VALUE
nurat_cmp(VALUE self, VALUE other)
{
    switch (TYPE(other)) {
      case T_FIXNUM:
      case T_BIGNUM:
	{
	    get_dat1(self);

	    if (FIXNUM_P(dat->den) && FIX2LONG(dat->den) == 1)
		return f_cmp(dat->num, other);
	    else
		return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
	}
      case T_FLOAT:
	return f_cmp(f_to_f(self), other);
      case T_RATIONAL:
	{
	    VALUE num1, num2;

	    get_dat2(self, other);

	    if (FIXNUM_P(adat->num) && FIXNUM_P(adat->den) &&
		FIXNUM_P(bdat->num) && FIXNUM_P(bdat->den)) {
		num1 = f_imul(FIX2LONG(adat->num), FIX2LONG(bdat->den));
		num2 = f_imul(FIX2LONG(bdat->num), FIX2LONG(adat->den));
	    }
	    else {
		num1 = f_mul(adat->num, bdat->den);
		num2 = f_mul(bdat->num, adat->den);
	    }
	    return f_cmp(f_sub(num1, num2), ZERO);
	}
      default:
	return rb_num_coerce_bin(self, other, id_cmp);
    }
}
コード例 #15
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
/*
 * call-seq:
 *    rat == object  ->  true or false
 *
 * Returns true if rat equals object numerically.
 *
 * For example:
 *
 *    Rational(2, 3)  == Rational(2, 3)   #=> true
 *    Rational(5)     == 5                #=> true
 *    Rational(0)     == 0.0              #=> true
 *    Rational('1/3') == 0.33             #=> false
 *    Rational('1/2') == '1/2'            #=> false
 */
static VALUE
nurat_eqeq_p(VALUE self, SEL sel, VALUE other)
{
    switch (TYPE(other)) {
      case T_FIXNUM:
      case T_BIGNUM:
	{
	    get_dat1(self);

	    if (f_zero_p(dat->num) && f_zero_p(other))
		return Qtrue;

	    if (!FIXNUM_P(dat->den))
		return Qfalse;
	    if (FIX2LONG(dat->den) != 1)
		return Qfalse;
	    if (f_eqeq_p(dat->num, other))
		return Qtrue;
	    return Qfalse;
	}
      case T_FLOAT:
	return f_eqeq_p(f_to_f(self), other);
      case T_RATIONAL:
	{
	    get_dat2(self, other);

	    if (f_zero_p(adat->num) && f_zero_p(bdat->num))
		return Qtrue;

	    return f_boolcast(f_eqeq_p(adat->num, bdat->num) &&
			      f_eqeq_p(adat->den, bdat->den));
	}
      default:
	return f_eqeq_p(other, self);
    }
}
コード例 #16
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.imag       ->  real
 *    cmp.imaginary  ->  real
 *
 * Returns the imaginary part.
 *
 *    Complex(7).imaginary      #=> 0
 *    Complex(9, -4).imaginary  #=> -4
 */
static VALUE
nucomp_imag(VALUE self)
{
    get_dat1(self);
    return dat->imag;
}
コード例 #17
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.real  ->  real
 *
 * Returns the real part.
 *
 *    Complex(7).real      #=> 7
 *    Complex(9, -4).real  #=> 9
 */
static VALUE
nucomp_real(VALUE self)
{
    get_dat1(self);
    return dat->real;
}
コード例 #18
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
static VALUE
nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, backref;

    rb_scan_args(argc, argv, "11", &a1, &a2);

    if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
	rb_raise(rb_eTypeError, "can't convert nil into Complex");

    backref = rb_backref_get();
    rb_match_busy(backref);

    if (RB_TYPE_P(a1, T_STRING)) {
	a1 = string_to_c_strict(a1);
    }

    if (RB_TYPE_P(a2, T_STRING)) {
	a2 = string_to_c_strict(a2);
    }

    rb_backref_set(backref);

    if (RB_TYPE_P(a1, T_COMPLEX)) {
	{
	    get_dat1(a1);

	    if (k_exact_zero_p(dat->imag))
		a1 = dat->real;
	}
    }

    if (RB_TYPE_P(a2, T_COMPLEX)) {
	{
	    get_dat1(a2);

	    if (k_exact_zero_p(dat->imag))
		a2 = dat->real;
	}
    }

    if (RB_TYPE_P(a1, T_COMPLEX)) {
	if (argc == 1 || (k_exact_zero_p(a2)))
	    return a1;
    }

    if (argc == 1) {
	if (k_numeric_p(a1) && !f_real_p(a1))
	    return a1;
	/* should raise exception for consistency */
	if (!k_numeric_p(a1))
	    return rb_convert_type(a1, T_COMPLEX, "Complex", "to_c");
    }
    else {
	if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
	    (!f_real_p(a1) || !f_real_p(a2)))
	    return f_add(a1,
			 f_mul(a2,
			       f_complex_new_bang2(rb_cComplex, ZERO, ONE)));
    }

    {
	VALUE argv2[2];
	argv2[0] = a1;
	argv2[1] = a2;
	return nucomp_s_new(argc, argv2, klass);
    }
}
コード例 #19
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
/*
 * call-seq:
 *    rat.denominator  ->  integer
 *
 * Returns the denominator (always positive).
 *
 * For example:
 *
 *    Rational(7).denominator             #=> 1
 *    Rational(7, 1).denominator          #=> 1
 *    Rational(9, -4).denominator         #=> 4
 *    Rational(-2, -10).denominator       #=> 5
 *    rat.numerator.gcd(rat.denominator)  #=> 1
 */
static VALUE
nurat_denominator(VALUE self, SEL sel)
{
    get_dat1(self);
    return dat->den;
}
コード例 #20
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/* :nodoc: */
static VALUE
nucomp_exact_p(VALUE self)
{
    get_dat1(self);
    return f_boolcast(k_exact_p(dat->real) && k_exact_p(dat->imag));
}
コード例 #21
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.conj       ->  complex
 *    cmp.conjugate  ->  complex
 *
 * Returns the complex conjugate.
 *
 *    Complex(1, 2).conjugate  #=> (1-2i)
 */
static VALUE
nucomp_conj(VALUE self)
{
    get_dat1(self);
    return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}
コード例 #22
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.rect         ->  array
 *    cmp.rectangular  ->  array
 *
 * Returns an array; [cmp.real, cmp.imag].
 *
 *    Complex(1, 2).rectangular  #=> [1, 2]
 */
static VALUE
nucomp_rect(VALUE self)
{
    get_dat1(self);
    return rb_assoc_new(dat->real, dat->imag);
}
コード例 #23
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
static VALUE
nurat_ceil(VALUE self, SEL sel)
{
    get_dat1(self);
    return f_negate(f_idiv(f_negate(dat->num), dat->den));
}
コード例 #24
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
/*
 * call-seq:
 *    rat.to_f  ->  float
 *
 * Return the value as a float.
 *
 * For example:
 *
 *    Rational(2).to_f      #=> 2.0
 *    Rational(9, 4).to_f   #=> 2.25
 *    Rational(-3, 4).to_f  #=> -0.75
 *    Rational(20, 3).to_f  #=> 6.666666666666667
 */
static VALUE
nurat_to_f(VALUE self, SEL sel)
{
    get_dat1(self);
    return f_fdiv(dat->num, dat->den);
}
コード例 #25
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
VALUE
rb_rational_reciprocal(VALUE x, SEL sel)
{
    get_dat1(x);
    return f_rational_new_no_reduce2(CLASS_OF(x), dat->den, dat->num);
}
コード例 #26
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.denominator  ->  integer
 *
 * Returns the denominator (lcm of both denominator - real and imag).
 *
 * See numerator.
 */
static VALUE
nucomp_denominator(VALUE self)
{
    get_dat1(self);
    return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
}
コード例 #27
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp ** numeric  ->  complex
 *
 * Performs exponentiation.
 *
 *    Complex('i') ** 2              #=> (-1+0i)
 *    Complex(-8) ** Rational(1, 3)  #=> (1.0000000000000002+1.7320508075688772i)
 */
static VALUE
nucomp_expt(VALUE self, VALUE other)
{
    if (k_numeric_p(other) && k_exact_zero_p(other))
	return f_complex_new_bang1(CLASS_OF(self), ONE);

    if (k_rational_p(other) && f_one_p(f_denominator(other)))
	other = f_numerator(other); /* c14n */

    if (k_complex_p(other)) {
	get_dat1(other);

	if (k_exact_zero_p(dat->imag))
	    other = dat->real; /* c14n */
    }

    if (k_complex_p(other)) {
	VALUE r, theta, nr, ntheta;

	get_dat1(other);

	r = f_abs(self);
	theta = f_arg(self);

	nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
			      f_mul(dat->imag, theta)));
	ntheta = f_add(f_mul(theta, dat->real),
		       f_mul(dat->imag, m_log_bang(r)));
	return f_complex_polar(CLASS_OF(self), nr, ntheta);
    }
    if (k_fixnum_p(other)) {
	if (f_gt_p(other, ZERO)) {
	    VALUE x, z;
	    long n;

	    x = self;
	    z = x;
	    n = FIX2LONG(other) - 1;

	    while (n) {
		long q, r;

		while (1) {
		    get_dat1(x);

		    q = n / 2;
		    r = n % 2;

		    if (r)
			break;

		    x = nucomp_s_new_internal(CLASS_OF(self),
				       f_sub(f_mul(dat->real, dat->real),
					     f_mul(dat->imag, dat->imag)),
				       f_mul(f_mul(TWO, dat->real), dat->imag));
		    n = q;
		}
		z = f_mul(z, x);
		n--;
	    }
	    return z;
	}
	return f_expt(f_reciprocal(self), f_negate(other));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	VALUE r, theta;

	if (k_bignum_p(other))
	    rb_warn("in a**b, b may be too big");

	r = f_abs(self);
	theta = f_arg(self);

	return f_complex_polar(CLASS_OF(self), f_expt(r, other),
			       f_mul(theta, other));
    }
    return rb_num_coerce_bin(self, other, id_expt);
}
コード例 #28
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
static VALUE
nurat_floor(VALUE self, SEL sel)
{
    get_dat1(self);
    return f_idiv(dat->num, dat->den);
}
コード例 #29
0
ファイル: complex.c プロジェクト: gogotanaka/ruby_svn
/*
 * call-seq:
 *    cmp.arg    ->  float
 *    cmp.angle  ->  float
 *    cmp.phase  ->  float
 *
 * Returns the angle part of its polar form.
 *
 *    Complex.polar(3, Math::PI/2).arg  #=> 1.5707963267948966
 */
static VALUE
nucomp_arg(VALUE self)
{
    get_dat1(self);
    return m_atan2_bang(dat->imag, dat->real);
}
コード例 #30
0
ファイル: rational.c プロジェクト: alloy/mr-experimental
/*
 * call-seq:
 *    rat.numerator  ->  integer
 *
 * Returns the numerator.
 *
 * For example:
 *
 *    Rational(7).numerator        #=> 7
 *    Rational(7, 1).numerator     #=> 7
 *    Rational(9, -4).numerator    #=> -9
 *    Rational(-2, -10).numerator  #=> 1
 */
static VALUE
nurat_numerator(VALUE self, SEL sel)
{
    get_dat1(self);
    return dat->num;
}