mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user