Move default `Integer#/` from `rational.c` to `complex.c`.

parent 01a8edea
...@@ -4,5 +4,4 @@ MRuby::Gem::Specification.new('mruby-complex') do |spec| ...@@ -4,5 +4,4 @@ MRuby::Gem::Specification.new('mruby-complex') do |spec|
spec.summary = 'Complex class' spec.summary = 'Complex class'
spec.build.defines << "MRB_USE_COMPLEX" spec.build.defines << "MRB_USE_COMPLEX"
spec.add_dependency 'mruby-math', core: 'mruby-math' spec.add_dependency 'mruby-math', core: 'mruby-math'
spec.add_test_dependency('mruby-rational')
end end
...@@ -332,15 +332,16 @@ complex_div(mrb_state *mrb, mrb_value self) ...@@ -332,15 +332,16 @@ complex_div(mrb_state *mrb, mrb_value self)
return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x)); return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x));
} }
#ifndef MRB_USE_RATIONAL
mrb_int mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y); mrb_int mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
mrb_value mrb_rational_new(mrb_state *mrb, mrb_int n, mrb_int d);
mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x);
/* 15.2.8.3.4 */ /* 15.2.8.3.4 */
/* /*
* redefine Integer#/ * redefine Integer#/
*/ */
static mrb_value static mrb_value
int_div(mrb_state *mrb, mrb_value x) cpx_int_div(mrb_state *mrb, mrb_value x)
{ {
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
mrb_int a = mrb_integer(x); mrb_int a = mrb_integer(x);
...@@ -350,9 +351,13 @@ int_div(mrb_state *mrb, mrb_value x) ...@@ -350,9 +351,13 @@ int_div(mrb_state *mrb, mrb_value x)
return mrb_int_value(mrb, div); return mrb_int_value(mrb, div);
} }
switch (mrb_type(y)) { switch (mrb_type(y)) {
#ifdef MRB_USE_RATIONAL
case MRB_TT_RATIONAL:
return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1));
#endif
case MRB_TT_COMPLEX: case MRB_TT_COMPLEX:
x = complex_new(mrb, (mrb_float)a, 0); x = complex_new(mrb, (mrb_float)a, 0);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); return complex_div(mrb, x);
default: default:
return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y))); return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
} }
...@@ -364,23 +369,27 @@ int_div(mrb_state *mrb, mrb_value x) ...@@ -364,23 +369,27 @@ int_div(mrb_state *mrb, mrb_value x)
*/ */
static mrb_value static mrb_value
int_quo(mrb_state *mrb, mrb_value x) cpx_int_quo(mrb_state *mrb, mrb_value x)
{ {
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
mrb_int a = mrb_integer(x); mrb_int a = mrb_integer(x);
switch (mrb_type(y)) { switch (mrb_type(y)) {
#ifdef MRB_USE_RATIONAL
case MRB_TT_RATIONAL:
x = mrb_rational_new(mrb, a, 1);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
#endif
case MRB_TT_COMPLEX: case MRB_TT_COMPLEX:
x = complex_new(mrb, (mrb_float)a, 0); x = complex_new(mrb, (mrb_float)a, 0);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); return complex_div(mrb, x);
default: default:
return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y))); return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
} }
} }
#endif
static mrb_value static mrb_value
flo_div(mrb_state *mrb, mrb_value x) cpx_flo_div(mrb_state *mrb, mrb_value x)
{ {
mrb_float a = mrb_float(x); mrb_float a = mrb_float(x);
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
...@@ -423,12 +432,10 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) ...@@ -423,12 +432,10 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb)
mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1));
mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1));
mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1));
#ifndef MRB_USE_RATIONAL mrb_define_method(mrb, mrb->integer_class, "/", cpx_int_div, MRB_ARGS_REQ(1)); /* overrride */
mrb_define_method(mrb, mrb->integer_class, "/", int_div, MRB_ARGS_REQ(1)); /* overrride */ mrb_define_method(mrb, mrb->integer_class, "quo", cpx_int_quo, MRB_ARGS_REQ(1)); /* overrride */
mrb_define_method(mrb, mrb->integer_class, "quo", int_quo, MRB_ARGS_REQ(1)); /* overrride */ mrb_define_method(mrb, mrb->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */
#endif mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */
mrb_define_method(mrb, mrb->float_class, "/", flo_div, MRB_ARGS_REQ(1)); /* overrride */
mrb_define_method(mrb, mrb->float_class, "quo", flo_div, MRB_ARGS_REQ(1)); /* overrride */
} }
void void
......
...@@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-rational') do |spec| ...@@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-rational') do |spec|
spec.author = 'mruby developers' spec.author = 'mruby developers'
spec.summary = 'Rational class' spec.summary = 'Rational class'
spec.build.defines << "MRB_USE_RATIONAL" spec.build.defines << "MRB_USE_RATIONAL"
spec.add_test_dependency('mruby-complex')
end end
...@@ -75,8 +75,8 @@ rat_zerodiv(mrb_state *mrb) ...@@ -75,8 +75,8 @@ rat_zerodiv(mrb_state *mrb)
mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0 in rational"); mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0 in rational");
} }
static mrb_value mrb_value
rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator) mrb_rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
{ {
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Rational)); struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Rational));
struct mrb_rational *p; struct mrb_rational *p;
...@@ -99,6 +99,8 @@ rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator) ...@@ -99,6 +99,8 @@ rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
return mrb_obj_value(rat); return mrb_obj_value(rat);
} }
#define rational_new(mrb,n,d) mrb_rational_new(mrb, n, d)
inline static mrb_int inline static mrb_int
i_gcd(mrb_int x, mrb_int y) i_gcd(mrb_int x, mrb_int y)
{ {
...@@ -608,8 +610,8 @@ rational_mul(mrb_state *mrb, mrb_value x) ...@@ -608,8 +610,8 @@ rational_mul(mrb_state *mrb, mrb_value x)
mrb_int mrb_num_div_int(mrb_state *, mrb_int, mrb_int); mrb_int mrb_num_div_int(mrb_state *, mrb_int, mrb_int);
static mrb_value mrb_value
rational_div(mrb_state *mrb, mrb_value x) mrb_rational_div(mrb_state *mrb, mrb_value x)
{ {
struct mrb_rational *p1 = rational_ptr(mrb, x); struct mrb_rational *p1 = rational_ptr(mrb, x);
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
...@@ -650,12 +652,15 @@ rational_div(mrb_state *mrb, mrb_value x) ...@@ -650,12 +652,15 @@ rational_div(mrb_state *mrb, mrb_value x)
} }
} }
#define rational_div mrb_rational_div
#ifndef MRB_USE_COMPLEX
/* 15.2.8.3.4 */ /* 15.2.8.3.4 */
/* /*
* redefine Integer#/ * redefine Integer#/
*/ */
static mrb_value static mrb_value
int_div(mrb_state *mrb, mrb_value x) rat_int_div(mrb_state *mrb, mrb_value x)
{ {
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
mrb_int a = mrb_integer(x); mrb_int a = mrb_integer(x);
...@@ -666,16 +671,10 @@ int_div(mrb_state *mrb, mrb_value x) ...@@ -666,16 +671,10 @@ int_div(mrb_state *mrb, mrb_value x)
} }
switch (mrb_type(y)) { switch (mrb_type(y)) {
case MRB_TT_RATIONAL: case MRB_TT_RATIONAL:
x = rational_new(mrb, a, 1); return rational_div(mrb, rational_new(mrb, a, 1));
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
#if defined(MRB_USE_COMPLEX)
case MRB_TT_COMPLEX:
x = mrb_complex_new(mrb, (mrb_float)a, 0);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
#endif
case MRB_TT_FLOAT:
default: default:
#ifdef MRB_NO_FLOAT #ifdef MRB_NO_FLOAT
case MRB_TT_FLOAT:
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
#else #else
return mrb_float_value(mrb, mrb_num_div_flo(mrb, (mrb_float)a, mrb_to_flo(mrb, y))); return mrb_float_value(mrb, mrb_num_div_flo(mrb, (mrb_float)a, mrb_to_flo(mrb, y)));
...@@ -689,7 +688,7 @@ int_div(mrb_state *mrb, mrb_value x) ...@@ -689,7 +688,7 @@ int_div(mrb_state *mrb, mrb_value x)
*/ */
static mrb_value static mrb_value
int_quo(mrb_state *mrb, mrb_value x) rat_int_quo(mrb_state *mrb, mrb_value x)
{ {
mrb_value y = mrb_get_arg1(mrb); mrb_value y = mrb_get_arg1(mrb);
mrb_int a = mrb_integer(x); mrb_int a = mrb_integer(x);
...@@ -701,11 +700,6 @@ int_quo(mrb_state *mrb, mrb_value x) ...@@ -701,11 +700,6 @@ int_quo(mrb_state *mrb, mrb_value x)
case MRB_TT_RATIONAL: case MRB_TT_RATIONAL:
x = rational_new(mrb, a, 1); x = rational_new(mrb, a, 1);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
#if defined(MRB_USE_COMPLEX)
case MRB_TT_COMPLEX:
x = mrb_complex_new(mrb, (mrb_float)a, 0);
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
#endif
default: default:
#ifdef MRB_NO_FLOAT #ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
...@@ -714,6 +708,7 @@ int_quo(mrb_state *mrb, mrb_value x) ...@@ -714,6 +708,7 @@ int_quo(mrb_state *mrb, mrb_value x)
#endif #endif
} }
} }
#endif /* !MRB_USE_COMPLEX */
void mrb_mruby_rational_gem_init(mrb_state *mrb) void mrb_mruby_rational_gem_init(mrb_state *mrb)
{ {
...@@ -740,8 +735,10 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) ...@@ -740,8 +735,10 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb)
mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1));
mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1));
mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE());
mrb_define_method(mrb, mrb->integer_class, "/", int_div, MRB_ARGS_REQ(1)); /* overrride */ #ifndef MRB_USE_COMPLEX
mrb_define_method(mrb, mrb->integer_class, "quo", int_quo, MRB_ARGS_REQ(1)); /* overrride */ mrb_define_method(mrb, mrb->integer_class, "/", rat_int_div, MRB_ARGS_REQ(1)); /* overrride */
mrb_define_method(mrb, mrb->integer_class, "quo", rat_int_quo, MRB_ARGS_REQ(1)); /* overrride */
#endif
mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1));
} }
......
...@@ -24,6 +24,7 @@ end ...@@ -24,6 +24,7 @@ end
def assert_rational(exp, real) def assert_rational(exp, real)
assert "assert_rational" do assert "assert_rational" do
assert_kind_of Rational, real
assert_float exp.numerator, real.numerator assert_float exp.numerator, real.numerator
assert_float exp.denominator, real.denominator assert_float exp.denominator, real.denominator
end end
...@@ -135,7 +136,7 @@ assert 'Rational#/' do ...@@ -135,7 +136,7 @@ assert 'Rational#/' do
assert_rational(Rational(32, 9), 4 / Rational(9, 8)) assert_rational(Rational(32, 9), 4 / Rational(9, 8))
assert_float( 0.22675736961451246, Rational(20, 9) / 9.8) assert_float( 0.22675736961451246, Rational(20, 9) / 9.8)
assert_float( 4.41, 9.8 / Rational(20, 9)) assert_float( 4.41, 9.8 / Rational(20, 9))
assert_complex(1.92, 1.44) {Rational(24,2)/(4.0+3i)} assert_complex(1.92, 1.44) {Rational(24,2)/(4.0-3i)}
assert_complex(0.25, 0.25) {(3.0+3i)/Rational(24,2)} assert_complex(0.25, 0.25) {(3.0+3i)/Rational(24,2)}
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment