summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-complex/src/complex.c52
-rw-r--r--mrbgems/mruby-complex/test/complex.rb12
-rw-r--r--mrbgems/mruby-rational/mrbgem.rake1
-rw-r--r--mrbgems/mruby-rational/src/rational.c60
-rw-r--r--mrbgems/mruby-rational/test/rational.rb3
-rw-r--r--src/numeric.c16
-rw-r--r--src/vm.c8
7 files changed, 84 insertions, 68 deletions
diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c
index 086ada7ad..0bf5377ed 100644
--- a/mrbgems/mruby-complex/src/complex.c
+++ b/mrbgems/mruby-complex/src/complex.c
@@ -236,8 +236,7 @@ complex_mul(mrb_state *mrb, mrb_value x)
}
#ifndef MRB_NO_FLOAT
-mrb_float mrb_num_div_flo(mrb_state*, mrb_float, mrb_float);
-#define div_flo(x,y) mrb_num_div_flo(NULL, x, y)
+mrb_float mrb_div_flo(mrb_float, mrb_float);
#endif
/* Arithmetic on (significand, exponent) pairs avoids premature overflow in
@@ -276,7 +275,7 @@ static void
div_pair(struct float_pair *q, struct float_pair const *a,
struct float_pair const *b)
{
- q->s = div_flo(a->s, b->s);
+ q->s = mrb_div_flo(a->s, b->s);
q->x = a->x - b->x;
}
@@ -289,7 +288,7 @@ complex_div(mrb_state *mrb, mrb_value self)
a = complex_ptr(mrb, self);
if (mrb_type(rhs) != MRB_TT_COMPLEX) {
mrb_float f = mrb_to_flo(mrb, rhs);
- return complex_new(mrb, div_flo(a->real, f), div_flo(a->imaginary, f));
+ return complex_new(mrb, mrb_div_flo(a->real, f), mrb_div_flo(a->imaginary, f));
}
struct float_pair ar, ai, br, bi;
@@ -332,29 +331,34 @@ complex_div(mrb_state *mrb, mrb_value self)
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_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 */
/*
* redefine Integer#/
*/
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_int a = mrb_integer(x);
if (mrb_integer_p(y)) {
- mrb_int div = mrb_num_div_int(mrb, a, mrb_integer(y));
+ mrb_int div = mrb_div_int(mrb, a, mrb_integer(y));
return mrb_int_value(mrb, div);
}
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:
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:
- return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
+ return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
}
}
@@ -364,23 +368,27 @@ int_div(mrb_state *mrb, mrb_value x)
*/
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_int a = mrb_integer(x);
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:
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:
- return mrb_float_value(mrb, div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
+ return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
}
}
-#endif
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_value y = mrb_get_arg1(mrb);
@@ -389,10 +397,10 @@ flo_div(mrb_state *mrb, mrb_value x)
case MRB_TT_COMPLEX:
return complex_div(mrb, complex_new(mrb, a, 0));
case MRB_TT_FLOAT:
- a = div_flo(a, mrb_float(y));
+ a = mrb_div_flo(a, mrb_float(y));
return mrb_float_value(mrb, a);
default:
- a = div_flo(a, mrb_to_flo(mrb, y));
+ a = mrb_div_flo(a, mrb_to_flo(mrb, y));
return mrb_float_value(mrb, a);
}
}
@@ -423,12 +431,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, "quo", complex_div, 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, "/", int_div, MRB_ARGS_REQ(1)); /* overrride */
- mrb_define_method(mrb, mrb->integer_class, "quo", int_quo, MRB_ARGS_REQ(1)); /* overrride */
-#endif
- 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 */
+ mrb_define_method(mrb, mrb->integer_class, "/", cpx_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->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */
+ mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */
}
void
diff --git a/mrbgems/mruby-complex/test/complex.rb b/mrbgems/mruby-complex/test/complex.rb
index 8f9634048..85ee6e998 100644
--- a/mrbgems/mruby-complex/test/complex.rb
+++ b/mrbgems/mruby-complex/test/complex.rb
@@ -31,6 +31,8 @@ assert 'Complex#*' do
assert_complex Complex(-2, 9) * Complex(-9, 2), (0 - 85i)
assert_complex Complex(9, 8) * 4, (36 + 32i)
assert_complex Complex(20, 9) * 9.8, (196.0 + 88.2i)
+ assert_complex 4 * Complex(9, 8), (36 + 32i)
+ assert_complex 9.8 * Complex(20, 9), (196.0 + 88.2i)
end
assert 'Complex#+' do
@@ -39,6 +41,8 @@ assert 'Complex#+' do
assert_complex Complex(-2, 9) + Complex(-9, 2), (-11 + 11i)
assert_complex Complex(9, 8) + 4 , (13 + 8i)
assert_complex Complex(20, 9) + 9.8 , (29.8 + 9i)
+ assert_complex 4 + Complex(9, 8) , (13 + 8i)
+ assert_complex 9.8 + Complex(20, 9) , (29.8 + 9i)
end
assert 'Complex#-' do
@@ -47,10 +51,12 @@ assert 'Complex#-' do
assert_complex Complex(-2, 9) - Complex(-9, 2), (7 + 7i)
assert_complex Complex(9, 8) - 4 , (5 + 8i)
assert_complex Complex(20, 9) - 9.8 , (10.2 + 9i)
+ assert_complex 4 - Complex(9, 8) , (-5 - 8i)
+ assert_complex 10.5 - Complex(20, 9) , (-9.5 - 9i)
end
assert 'Complex#-@' do
- assert_complex(-Complex(1, 2), (-1 - 2i))
+ assert_complex((-1 - 2i), -Complex(1, 2))
end
assert 'Complex#/' do
@@ -59,6 +65,8 @@ assert 'Complex#/' do
assert_complex Complex(-2, 9) / Complex(-9, 2), ((36.0 / 85) - (77i / 85))
assert_complex Complex(9, 8) / 4 , ((9.0 / 4) + 2i)
assert_complex Complex(20, 9) / 9.8 , (2.0408163265306123 + 0.9183673469387754i)
+ assert_complex 4 / Complex(9, 8) , (0.2482758620689655 - 0.2206896551724138i)
+ assert_complex 9.8 / Complex(20, 9) , (0.4074844074844075 - 0.1833679833679834i)
if 1e39.infinite? then
# MRB_USE_FLOAT32 in effect
ten = 1e21
@@ -74,6 +82,8 @@ assert 'Complex#==' do
assert_true Complex(2, 3) == Complex(2, 3)
assert_true Complex(5) == 5
assert_true Complex(0) == 0.0
+ assert_true 5 == Complex(5)
+ assert_true 0.0 == Complex(0)
end
assert 'Complex#abs' do
diff --git a/mrbgems/mruby-rational/mrbgem.rake b/mrbgems/mruby-rational/mrbgem.rake
index ab5dc5fd1..534114862 100644
--- a/mrbgems/mruby-rational/mrbgem.rake
+++ b/mrbgems/mruby-rational/mrbgem.rake
@@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-rational') do |spec|
spec.author = 'mruby developers'
spec.summary = 'Rational class'
spec.build.defines << "MRB_USE_RATIONAL"
+ spec.add_test_dependency('mruby-complex')
end
diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c
index f6ba296ae..1d53afb5c 100644
--- a/mrbgems/mruby-rational/src/rational.c
+++ b/mrbgems/mruby-rational/src/rational.c
@@ -75,8 +75,8 @@ rat_zerodiv(mrb_state *mrb)
mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0 in rational");
}
-static mrb_value
-rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
+mrb_value
+mrb_rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
{
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Rational));
struct mrb_rational *p;
@@ -99,6 +99,8 @@ rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
return mrb_obj_value(rat);
}
+#define rational_new(mrb,n,d) mrb_rational_new(mrb, n, d)
+
inline static mrb_int
i_gcd(mrb_int x, mrb_int y)
{
@@ -482,7 +484,7 @@ rational_minus(mrb_state *mrb, mrb_value x)
}
#ifndef MRB_NO_FLOAT
-mrb_float mrb_num_div_flo(mrb_state*, mrb_float, mrb_float);
+mrb_float mrb_div_flo(mrb_float, mrb_float);
#endif
static mrb_value
@@ -515,7 +517,7 @@ rational_add(mrb_state *mrb, mrb_value x)
case MRB_TT_FLOAT:
{
mrb_float z = p1->numerator + mrb_float(y) * p1->denominator;
- return mrb_float_value(mrb, mrb_num_div_flo(mrb, z, (mrb_float)p1->denominator));
+ return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator));
}
#endif
@@ -561,7 +563,7 @@ rational_sub(mrb_state *mrb, mrb_value x)
default:
{
mrb_float z = p1->numerator - mrb_to_flo(mrb, y) * p1->denominator;
- return mrb_float_value(mrb, mrb_num_div_flo(mrb, z, (mrb_float)p1->denominator));
+ return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator));
}
#else
default:
@@ -597,7 +599,7 @@ rational_mul(mrb_state *mrb, mrb_value x)
case MRB_TT_FLOAT:
{
mrb_float z = p1->numerator * mrb_float(y);
- return mrb_float_value(mrb, mrb_num_div_flo(mrb, z, (mrb_float)p1->denominator));
+ return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator));
}
#endif
@@ -606,10 +608,8 @@ rational_mul(mrb_state *mrb, mrb_value x)
}
}
-mrb_int mrb_num_div_int(mrb_state *, mrb_int, mrb_int);
-
-static mrb_value
-rational_div(mrb_state *mrb, mrb_value x)
+mrb_value
+mrb_rational_div(mrb_state *mrb, mrb_value x)
{
struct mrb_rational *p1 = rational_ptr(mrb, x);
mrb_value y = mrb_get_arg1(mrb);
@@ -641,8 +641,8 @@ rational_div(mrb_state *mrb, mrb_value x)
#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
{
- mrb_float z = mrb_num_div_flo(mrb, p1->numerator, mrb_to_flo(mrb, y));
- return mrb_float_value(mrb, mrb_num_div_flo(mrb, z, (mrb_float)p1->denominator));
+ mrb_float z = mrb_div_flo(p1->numerator, mrb_to_flo(mrb, y));
+ return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator));
}
#else
mrb_raise(mrb, E_TYPE_ERROR, "non integer division");
@@ -650,35 +650,33 @@ rational_div(mrb_state *mrb, mrb_value x)
}
}
+#define rational_div mrb_rational_div
+mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int);
+
+#ifndef MRB_USE_COMPLEX
/* 15.2.8.3.4 */
/*
* redefine Integer#/
*/
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_int a = mrb_integer(x);
if (mrb_integer_p(y)) {
- mrb_int div = mrb_num_div_int(mrb, a, mrb_integer(y));
+ mrb_int div = mrb_div_int(mrb, a, mrb_integer(y));
return mrb_int_value(mrb, div);
}
switch (mrb_type(y)) {
case MRB_TT_RATIONAL:
- x = 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:
+ return rational_div(mrb, rational_new(mrb, a, 1));
default:
#ifdef MRB_NO_FLOAT
+ case MRB_TT_FLOAT:
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
#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_div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
#endif
}
}
@@ -689,7 +687,7 @@ int_div(mrb_state *mrb, mrb_value x)
*/
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_int a = mrb_integer(x);
@@ -701,19 +699,15 @@ int_quo(mrb_state *mrb, mrb_value x)
case MRB_TT_RATIONAL:
x = 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
default:
#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
#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_div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
#endif
}
}
+#endif /* !MRB_USE_COMPLEX */
void mrb_mruby_rational_gem_init(mrb_state *mrb)
{
@@ -740,8 +734,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, "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, "/", int_div, MRB_ARGS_REQ(1)); /* overrride */
- mrb_define_method(mrb, mrb->integer_class, "quo", int_quo, MRB_ARGS_REQ(1)); /* overrride */
+#ifndef MRB_USE_COMPLEX
+ 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));
}
diff --git a/mrbgems/mruby-rational/test/rational.rb b/mrbgems/mruby-rational/test/rational.rb
index 4a619a646..b807ef83f 100644
--- a/mrbgems/mruby-rational/test/rational.rb
+++ b/mrbgems/mruby-rational/test/rational.rb
@@ -24,6 +24,7 @@ end
def assert_rational(exp, real)
assert "assert_rational" do
+ assert_kind_of Rational, real
assert_float exp.numerator, real.numerator
assert_float exp.denominator, real.denominator
end
@@ -135,7 +136,7 @@ assert 'Rational#/' do
assert_rational(Rational(32, 9), 4 / Rational(9, 8))
assert_float( 0.22675736961451246, Rational(20, 9) / 9.8)
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)}
end
diff --git a/src/numeric.c b/src/numeric.c
index c5c862a37..edb5d28b2 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -119,7 +119,7 @@ int_pow(mrb_state *mrb, mrb_value x)
}
mrb_int
-mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
+mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
{
if (y == 0) {
int_zerodiv(mrb);
@@ -139,6 +139,8 @@ mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
return 0;
}
+mrb_float mrb_div_flo(mrb_float x, mrb_float y);
+
/* 15.2.8.3.4 */
/* 15.2.9.3.4 */
/*
@@ -156,13 +158,13 @@ int_div(mrb_state *mrb, mrb_value x)
mrb_int a = mrb_integer(x);
if (mrb_integer_p(y)) {
- mrb_int div = mrb_num_div_int(mrb, a, mrb_integer(y));
+ mrb_int div = mrb_div_int(mrb, a, mrb_integer(y));
return mrb_int_value(mrb, div);
}
#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non integer division");
#else
- return mrb_float_value(mrb, (mrb_float)a / mrb_to_flo(mrb, y));
+ return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y)));
#endif
}
@@ -248,12 +250,12 @@ flo_idiv(mrb_state *mrb, mrb_value xv)
mrb_int y, div;
mrb_get_args(mrb, "i", &y);
- div = mrb_num_div_int(mrb, (mrb_int)mrb_float(xv), y);
+ div = mrb_div_int(mrb, (mrb_int)mrb_float(xv), y);
return mrb_int_value(mrb, (mrb_int)div);
}
mrb_float
-mrb_num_div_flo(mrb_state *mrb, mrb_float x, mrb_float y)
+mrb_div_flo(mrb_float x, mrb_float y)
{
if (y != 0.0) {
return x / y;
@@ -273,10 +275,10 @@ flo_div(mrb_state *mrb, mrb_value x)
mrb_float a = mrb_float(x);
if (mrb_float_p(y)) {
- a = mrb_num_div_flo(mrb, a, mrb_float(y));
+ a = mrb_div_flo(a, mrb_float(y));
}
else {
- a = mrb_num_div_flo(mrb, a, mrb_to_flo(mrb, y));
+ a = mrb_div_flo(a, mrb_to_flo(mrb, y));
}
return mrb_float_value(mrb, a);
}
diff --git a/src/vm.c b/src/vm.c
index 5301c53f8..945bbe40b 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1085,6 +1085,8 @@ check_target_class(mrb_state *mrb)
}
void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
+mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
+mrb_float mrb_div_flo(mrb_float x, mrb_float y);
MRB_API mrb_value
mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
@@ -2381,9 +2383,7 @@ RETRY_TRY_BLOCK:
}
CASE(OP_DIV, B) {
- mrb_int mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
#ifndef MRB_NO_FLOAT
- mrb_float mrb_num_div_flo(mrb_state *mrb, mrb_float x, mrb_float y);
mrb_float x, y, f;
#endif
@@ -2393,7 +2393,7 @@ RETRY_TRY_BLOCK:
{
mrb_int x = mrb_integer(regs[a]);
mrb_int y = mrb_integer(regs[a+1]);
- mrb_int div = mrb_num_div_int(mrb, x, y);
+ mrb_int div = mrb_div_int(mrb, x, y);
SET_INT_VALUE(mrb, regs[a], div);
}
NEXT;
@@ -2418,7 +2418,7 @@ RETRY_TRY_BLOCK:
}
#ifndef MRB_NO_FLOAT
- f = mrb_num_div_flo(mrb, x, y);
+ f = mrb_div_flo(x, y);
SET_FLOAT_VALUE(mrb, regs[a], f);
#endif
NEXT;