summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-03-19 10:30:16 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-03-19 10:37:10 +0900
commitd3184e4a6d8b85a22dd46f4e2909492a0a08cab1 (patch)
treeb45f9be65a970d80d4b60401e44d053f3b78b394 /src
parent08f9d5bab5092fe1193dd100765079e3e4d746b9 (diff)
downloadmruby-d3184e4a6d8b85a22dd46f4e2909492a0a08cab1.tar.gz
mruby-d3184e4a6d8b85a22dd46f4e2909492a0a08cab1.zip
complex.c: overhaul complex operators.
- define `MRB_TT_COMPLEX` - change object structure (`struct RComplex`) - add memory management for `MRB_TT_COMPLEX` - avoid operator overloading as much as possible - as a result, performance improved a log - should work with and without `Rational` defined
Diffstat (limited to 'src')
-rw-r--r--src/gc.c13
-rw-r--r--src/numeric.c111
2 files changed, 82 insertions, 42 deletions
diff --git a/src/gc.c b/src/gc.c
index 9ea3c1712..0a38139eb 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -903,15 +903,22 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
}
break;
-#if defined(MRB_INT64) && defined(MRB_32BIT)
-#ifdef MRB_USE_RATIONAL
+#if defined(MRB_USE_RATIONAL) && defined(MRB_INT64) && defined(MRB_32BIT)
case MRB_TT_RATIONAL:
{
struct RData *o = (struct RData*)obj;
- mrb_free(mrb, obj->iv_tbl);
+ mrb_free(mrb, o->iv);
}
break;
#endif
+
+#if defined(MRB_USE_COMPLEX) && defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32)
+ case MRB_TT_COMPLEX:
+ {
+ struct RData *o = (struct RData*)obj;
+ mrb_free(mrb, o->iv);
+ }
+ break;
#endif
default:
diff --git a/src/numeric.c b/src/numeric.c
index 3eba71b78..c5c862a37 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -267,14 +267,18 @@ mrb_num_div_flo(mrb_state *mrb, mrb_float x, mrb_float y)
}
static mrb_value
-flo_div(mrb_state *mrb, mrb_value xv)
+flo_div(mrb_state *mrb, mrb_value x)
{
- mrb_float x, y;
+ mrb_value y = mrb_get_arg1(mrb);
+ mrb_float a = mrb_float(x);
- x = mrb_float(xv);
- mrb_get_args(mrb, "f", &y);
- x = mrb_num_div_flo(mrb, x, y);
- return mrb_float_value(mrb, x);
+ if (mrb_float_p(y)) {
+ a = mrb_num_div_flo(mrb, a, mrb_float(y));
+ }
+ else {
+ a = mrb_num_div_flo(mrb, a, mrb_to_flo(mrb, y));
+ }
+ return mrb_float_value(mrb, a);
}
/* 15.2.9.3.16(x) */
@@ -348,6 +352,32 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
return str;
}
+/* 15.2.9.3.1 */
+/*
+ * call-seq:
+ * float + other -> float
+ *
+ * Returns a new float which is the sum of <code>float</code>
+ * and <code>other</code>.
+ */
+static mrb_value
+flo_add(mrb_state *mrb, mrb_value x)
+{
+ mrb_value y = mrb_get_arg1(mrb);
+ mrb_float a = mrb_float(x);
+
+ switch (mrb_type(y)) {
+ case MRB_TT_FLOAT:
+ return mrb_float_value(mrb, a + mrb_float(y));
+#if defined(MRB_USE_COMPLEX)
+ case MRB_TT_COMPLEX:
+ return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x);
+#endif
+ default:
+ return mrb_float_value(mrb, a + mrb_to_flo(mrb, y));
+ }
+}
+
/* 15.2.9.3.2 */
/*
* call-seq:
@@ -358,11 +388,22 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
*/
static mrb_value
-flo_minus(mrb_state *mrb, mrb_value x)
+flo_sub(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
+ mrb_float a = mrb_float(x);
- return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
+ switch (mrb_type(y)) {
+ case MRB_TT_FLOAT:
+ return mrb_float_value(mrb, a - mrb_float(y));
+#if defined(MRB_USE_COMPLEX)
+ case MRB_TT_COMPLEX:
+ x = mrb_funcall_id(mrb, y, MRB_OPSYM(sub), 1, x);
+ return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0);
+#endif
+ default:
+ return mrb_float_value(mrb, a - mrb_to_flo(mrb, y));
+ }
}
/* 15.2.9.3.3 */
@@ -378,8 +419,18 @@ static mrb_value
flo_mul(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
+ mrb_float a = mrb_float(x);
- return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
+ switch (mrb_type(y)) {
+ case MRB_TT_FLOAT:
+ return mrb_float_value(mrb, a * mrb_float(y));
+#if defined(MRB_USE_COMPLEX)
+ case MRB_TT_COMPLEX:
+ return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x);
+#endif
+ default:
+ return mrb_float_value(mrb, a * mrb_to_flo(mrb, y));
+ }
}
static void
@@ -1328,7 +1379,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
#endif
static mrb_value
-fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
+int_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
@@ -1362,7 +1413,7 @@ MRB_API mrb_value
mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
if (mrb_integer_p(x)) {
- return fixnum_plus(mrb, x, y);
+ return int_plus(mrb, x, y);
}
#ifndef MRB_NO_FLOAT
if (mrb_float_p(x)) {
@@ -1392,15 +1443,15 @@ mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
* result.
*/
static mrb_value
-int_plus(mrb_state *mrb, mrb_value self)
+int_add(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
- return fixnum_plus(mrb, self, other);
+ return int_plus(mrb, self, other);
}
static mrb_value
-fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
+int_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
@@ -1434,7 +1485,7 @@ MRB_API mrb_value
mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
if (mrb_integer_p(x)) {
- return fixnum_minus(mrb, x, y);
+ return int_minus(mrb, x, y);
}
#ifndef MRB_NO_FLOAT
if (mrb_float_p(x)) {
@@ -1465,11 +1516,11 @@ mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
* result.
*/
static mrb_value
-int_minus(mrb_state *mrb, mrb_value self)
+int_sub(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
- return fixnum_minus(mrb, self, other);
+ return int_minus(mrb, self, other);
}
@@ -1685,24 +1736,6 @@ num_infinite_p(mrb_state *mrb, mrb_value self)
return mrb_false_value();
}
-/* 15.2.9.3.1 */
-/*
- * call-seq:
- * float + other -> float
- *
- * Returns a new float which is the sum of <code>float</code>
- * and <code>other</code>.
- */
-#ifndef MRB_NO_FLOAT
-static mrb_value
-flo_plus(mrb_state *mrb, mrb_value x)
-{
- mrb_value y = mrb_get_arg1(mrb);
-
- return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
-}
-#endif
-
/* ------------------------------------------------------------------------*/
void
mrb_init_numeric(mrb_state *mrb)
@@ -1737,8 +1770,8 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.26 */
#endif
- mrb_define_method(mrb, integer, "+", int_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
- mrb_define_method(mrb, integer, "-", int_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */
+ mrb_define_method(mrb, integer, "+", int_add, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
+ mrb_define_method(mrb, integer, "-", int_sub, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */
mrb_define_method(mrb, integer, "*", int_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */
mrb_define_method(mrb, integer, "%", int_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */
mrb_define_method(mrb, integer, "/", int_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.6 */
@@ -1772,8 +1805,8 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */
mrb_define_method(mrb, fl, "quo", flo_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
mrb_define_method(mrb, fl, "div", flo_idiv, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */
- mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.4 */
+ mrb_define_method(mrb, fl, "+", flo_add, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */
+ mrb_define_method(mrb, fl, "-", flo_sub, MRB_ARGS_REQ(1)); /* 15.2.9.3.4 */
mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */
mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */
mrb_define_method(mrb, fl, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */