summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-03-24 11:06:14 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-03-24 11:06:14 +0900
commit9ed212ef9eedb09c5368a338ff905e25cdba149f (patch)
treebbbb2cb4da9931ce252063096c3a89ed58022c6e
parentfa3ac351ff86efe517180afa6159679887656ced (diff)
downloadmruby-9ed212ef9eedb09c5368a338ff905e25cdba149f.tar.gz
mruby-9ed212ef9eedb09c5368a338ff905e25cdba149f.zip
complex.c: implement `Complex` addition and subtraction in C.
-rw-r--r--mrbgems/mruby-complex/mrblib/complex.rb16
-rw-r--r--mrbgems/mruby-complex/src/complex.c44
2 files changed, 44 insertions, 16 deletions
diff --git a/mrbgems/mruby-complex/mrblib/complex.rb b/mrbgems/mruby-complex/mrblib/complex.rb
index 105c56d40..cd000a6c6 100644
--- a/mrbgems/mruby-complex/mrblib/complex.rb
+++ b/mrbgems/mruby-complex/mrblib/complex.rb
@@ -19,22 +19,6 @@ class Complex < Numeric
Complex(-real, -imaginary)
end
- def +(rhs)
- if rhs.is_a? Complex
- Complex(real + rhs.real, imaginary + rhs.imaginary)
- elsif rhs.is_a? Numeric
- Complex(real + rhs, imaginary)
- end
- end
-
- def -(rhs)
- if rhs.is_a? Complex
- Complex(real - rhs.real, imaginary - rhs.imaginary)
- elsif rhs.is_a? Numeric
- Complex(real - rhs, imaginary)
- end
- end
-
def abs
Math.hypot imaginary, real
end
diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c
index b4217d4d6..5243ac1cc 100644
--- a/mrbgems/mruby-complex/src/complex.c
+++ b/mrbgems/mruby-complex/src/complex.c
@@ -172,6 +172,48 @@ complex_eq(mrb_state *mrb, mrb_value x)
}
static mrb_value
+complex_add(mrb_state *mrb, mrb_value x)
+{
+ mrb_value y = mrb_get_arg1(mrb);
+ struct mrb_complex *p1 = complex_ptr(mrb, x);
+
+ switch (mrb_type(y)) {
+ case MRB_TT_COMPLEX:
+ {
+ struct mrb_complex *p2 = complex_ptr(mrb, y);
+ return mrb_complex_new(mrb, p1->real+p2->real, p1->imaginary+p2->imaginary);
+ }
+
+ default:
+ {
+ mrb_float z = mrb_to_flo(mrb, y);
+ return mrb_complex_new(mrb, p1->real+z, p1->imaginary);
+ }
+ }
+}
+
+static mrb_value
+complex_sub(mrb_state *mrb, mrb_value x)
+{
+ mrb_value y = mrb_get_arg1(mrb);
+ struct mrb_complex *p1 = complex_ptr(mrb, x);
+
+ switch (mrb_type(y)) {
+ case MRB_TT_COMPLEX:
+ {
+ struct mrb_complex *p2 = complex_ptr(mrb, y);
+ return mrb_complex_new(mrb, p1->real-p2->real, p1->imaginary-p2->imaginary);
+ }
+
+ default:
+ {
+ mrb_float z = mrb_to_flo(mrb, y);
+ return mrb_complex_new(mrb, p1->real-z, p1->imaginary);
+ }
+ }
+}
+
+static mrb_value
complex_mul(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
@@ -386,6 +428,8 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb)
mrb_define_method(mrb, comp, "to_f", complex_to_f, MRB_ARGS_NONE());
mrb_define_method(mrb, comp, "to_i", complex_to_i, MRB_ARGS_NONE());
mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE());
+ mrb_define_method(mrb, comp, "+", complex_add, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, comp, "-", complex_sub, MRB_ARGS_REQ(1));
mrb_define_method(mrb, comp, "*", complex_mul, 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));