From fcab7ef377c943f2234790e9fd85e9ae6b5e07e7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 11 Jul 2024 08:39:47 +0900 Subject: [PATCH] numeric.c (int_div): fixed a bug regarding bigint / non-integer Non-integer means Complex or Rational. --- include/mruby/internal.h | 1 + mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c | 5 +++++ mrbgems/mruby-rational/src/rational.c | 20 ++++++++++++++++++++ src/numeric.c | 19 ++++++++++--------- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 9f8453eaa..8e8ae4595 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -126,6 +126,7 @@ mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_as_rational(mrb_state *mrb, mrb_value x); void mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y); #endif diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c index 13ca03932..1d9c64057 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c @@ -68,6 +68,11 @@ mrb_value mrb_rational_to_f(mrb_state *mrb, mrb_value x) { return mrb_nil_value(); } +mrb_value +mrb_as_rational(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} void mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y) { } diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 225a19636..45838e6eb 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -284,6 +284,26 @@ mrb_rational_to_i(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, p->numerator / p->denominator); } +mrb_value +mrb_as_rational(mrb_state *mrb, mrb_value x) +{ + switch(mrb_type(x)) { + case MRB_TT_INTEGER: + return rational_new_i(mrb, mrb_integer(x), 1); + case MRB_TT_RATIONAL: + return x; +#ifndef MRB_NO_FLOAT +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: +#endif + case MRB_TT_FLOAT: + return rational_new_f(mrb, mrb_as_float(mrb, x)); +#endif + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot convert to Rational", x); + } +} + static mrb_value rational_negative_p(mrb_state *mrb, mrb_value self) { diff --git a/src/numeric.c b/src/numeric.c index c0482d0d3..e0db40e76 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -155,31 +155,32 @@ int_div(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { - return mrb_bint_div(mrb, x, y); - } + if (mrb_bigint_p(y) || mrb_integer_p(y)) { + return mrb_bint_div(mrb, x, y); + } + } else #endif - mrb_int a = mrb_integer(x); - if (mrb_integer_p(y)) { - return mrb_div_int_value(mrb, a, mrb_integer(y)); + return mrb_div_int_value(mrb, mrb_integer(x), mrb_integer(y)); } switch (mrb_type(y)) { #ifdef MRB_USE_BIGINT + case MRB_TT_INTEGER: case MRB_TT_BIGINT: - return mrb_bint_div(mrb, mrb_bint_new_int(mrb, a), y); + return mrb_bint_div(mrb, mrb_as_bint(mrb, x), y); #endif #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: - return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); + return mrb_rational_div(mrb, mrb_as_rational(mrb, x), y); #endif #ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, (mrb_float)a, 0); + x = mrb_complex_new(mrb, mrb_as_float(mrb, x), 0); return mrb_complex_div(mrb, x, y); #endif #ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); + return mrb_float_value(mrb, mrb_div_float(mrb_as_float(mrb, x), mrb_as_float(mrb, y))); #endif default: mrb_int_noconv(mrb, y);