numeric.c (mrb_div_int): separate the function in two.

- mrb_div_int() does integer division in Ruby way (mdiv)
  returns mrb_int
- mrb_div_int_value() division with zero div and overflow checks.
  returns mrb_value
This commit is contained in:
Yukihiro "Matz" Matsumoto
2022-07-09 14:38:18 +09:00
parent f1275803c9
commit e1980d7596
4 changed files with 21 additions and 21 deletions
+2 -1
View File
@@ -74,7 +74,8 @@ mrb_irep_catch_handler_table(const struct mrb_irep *irep)
#endif
/* numeric */
mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
mrb_value mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y);
mrb_int mrb_div_int(mrb_int x, mrb_int y);
mrb_value mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y);
+1 -1
View File
@@ -867,7 +867,7 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst)
else { /* OP_DIV */
if (n == 0) goto normal;
if (n0 == MRB_INT_MIN && n == -1) goto normal;
n = mrb_div_int(s->mrb, n0, n);
n = mrb_div_int(n0, n);
}
s->pc = addr_pc(s, data0.addr);
gen_int(s, dst, n);
+17 -17
View File
@@ -107,7 +107,18 @@ mrb_int_pow(mrb_state *mrb, mrb_value x)
#define int_pow mrb_int_pow
mrb_int
mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
mrb_div_int(mrb_int x, mrb_int y)
{
mrb_int div = x / y;
if ((x ^ y) < 0 && x != div * y) {
div -= 1;
}
return div;
}
mrb_value
mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y)
{
if (y == 0) {
mrb_int_zerodiv(mrb);
@@ -115,16 +126,7 @@ mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
else if(x == MRB_INT_MIN && y == -1) {
mrb_int_overflow(mrb, "division");
}
else {
mrb_int div = x / y;
if ((x ^ y) < 0 && x != div * y) {
div -= 1;
}
return div;
}
/* not reached */
return 0;
return mrb_int_value(mrb, mrb_div_int(x, y));
}
/* 15.2.8.3.4 */
@@ -156,8 +158,7 @@ int_div(mrb_state *mrb, mrb_value x)
return mrb_bint_mul_ii(mrb, a, b);
}
#endif
mrb_int div = mrb_div_int(mrb, a, b);
return mrb_int_value(mrb, div);
return mrb_div_int_value(mrb, a, b);
}
switch (mrb_type(y)) {
#ifdef MRB_USE_BIGINT
@@ -207,7 +208,7 @@ int_idiv(mrb_state *mrb, mrb_value x)
mrb_int y;
mrb_get_args(mrb, "i", &y);
return mrb_int_value(mrb, mrb_div_int(mrb, mrb_integer(x), y));
return mrb_div_int_value(mrb, mrb_integer(x), y);
}
static mrb_value
@@ -288,11 +289,10 @@ flo_pow(mrb_state *mrb, mrb_value x)
static mrb_value
flo_idiv(mrb_state *mrb, mrb_value xv)
{
mrb_int y, div;
mrb_int y;
mrb_get_args(mrb, "i", &y);
div = mrb_div_int(mrb, (mrb_int)mrb_float(xv), y);
return mrb_int_value(mrb, (mrb_int)div);
return mrb_div_int_value(mrb, (mrb_int)mrb_float(xv), y);
}
mrb_float
+1 -2
View File
@@ -2553,8 +2553,7 @@ RETRY_TRY_BLOCK:
{
mrb_int x = mrb_integer(regs[a]);
mrb_int y = mrb_integer(regs[a+1]);
mrb_int div = mrb_div_int(mrb, x, y);
SET_INT_VALUE(mrb, regs[a], div);
regs[a] = mrb_div_int_value(mrb, x, y);
}
NEXT;
#ifndef MRB_NO_FLOAT