GitHub

@@ -1611,16 +1611,26 @@ int_ceil(mrb_state *mrb, mrb_value x)

16111611

if (mrb_nil_p(f)) return x;

16121612

#ifdef MRB_USE_BIGINT

16131613

if (mrb_bigint_p(x)) {

1614-

return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f)));

1614+

x = mrb_bint_add_d(mrb, x, f);

1615+

return mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f));

16151616

}

16161617

#endif

16171618

mrb_int a = mrb_integer(x);

16181619

mrb_int b = mrb_integer(f);

1620+

mrb_int c = a % b;

16191621

int neg = a < 0;

1620-

if (neg) a = -a;

1621-

else a += b - 1;

1622-

a = a / b * b;

1623-

if (neg) a = -a;

1622+

a -= c;

1623+

if (!neg) {

1624+

if (mrb_int_add_overflow(a, b, &c)) {

1625+

#ifdef MRB_USE_BIGINT

1626+

x = mrb_bint_new_int(mrb, a);

1627+

return mrb_bint_add(mrb, x, f);

1628+

#else

1629+

mrb_int_overflow(mrb, "ceil");

1630+

#endif

1631+

}

1632+

a = c;

1633+

}

16241634

return mrb_int_value(mrb, a);

16251635

}

16261636

@@ -1648,10 +1658,20 @@ int_floor(mrb_state *mrb, mrb_value x)

16481658

#endif

16491659

mrb_int a = mrb_integer(x);

16501660

mrb_int b = mrb_integer(f);

1661+

mrb_int c = a % b;

16511662

int neg = a < 0;

1652-

if (neg) a = -a + b - 1;

1653-

a = a / b * b;

1654-

if (neg) a = -a;

1663+

a -= c;

1664+

if (neg) {

1665+

if (mrb_int_sub_overflow(a, b, &c)) {

1666+

#ifdef MRB_USE_BIGINT

1667+

x = mrb_bint_new_int(mrb, a);

1668+

return mrb_bint_sub(mrb, x, f);

1669+

#else

1670+

mrb_int_overflow(mrb, "floor");

1671+

#endif

1672+

}

1673+

a = c;

1674+

}

16551675

return mrb_int_value(mrb, a);

16561676

}

16571677

@@ -1677,7 +1697,7 @@ int_round(mrb_state *mrb, mrb_value x)

16771697

mrb_value r = mrb_bint_mod(mrb, x, f);

16781698

mrb_value n = mrb_bint_sub(mrb, x, r);

16791699

mrb_value h = mrb_bigint_p(f) ? mrb_bint_rshift(mrb, f, 1) : mrb_int_value(mrb, mrb_integer(f)>>1);

1680-

mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_integer(r) - mrb_integer(h));

1700+

mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_bigint_p(h) ? -mrb_bint_cmp(mrb, h, r) : (mrb_integer(r)-mrb_integer(h)));

16811701

if ((cmp > 0) || (cmp == 0 && mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) > 0)) {

16821702

n = mrb_as_bint(mrb, n);

16831703

n = mrb_bint_add(mrb, n, f);

@@ -1687,10 +1707,35 @@ int_round(mrb_state *mrb, mrb_value x)

16871707

#endif

16881708

mrb_int a = mrb_integer(x);

16891709

mrb_int b = mrb_integer(f);

1690-

int neg = a < 0;

1691-

if (neg) a = -a;

1692-

a = (a + b / 2) / b * b;

1693-

if (neg) a = -a;

1710+

mrb_int c = a % b;

1711+

a -= c;

1712+

if (c < 0) {

1713+

c = -c;

1714+

if (b/2 < c) {

1715+

if (mrb_int_sub_overflow(a, b, &c)) {

1716+

#ifdef MRB_USE_BIGINT

1717+

x = mrb_bint_new_int(mrb, a);

1718+

return mrb_bint_sub(mrb, x, f);

1719+

#else

1720+

mrb_int_overflow(mrb, "round");

1721+

#endif

1722+

}

1723+

}

1724+

a = c;

1725+

}

1726+

else {

1727+

if (b/2 < c) {

1728+

if (mrb_int_add_overflow(a, b, &c)) {

1729+

#ifdef MRB_USE_BIGINT

1730+

x = mrb_bint_new_int(mrb, a);

1731+

return mrb_bint_add(mrb, x, f);

1732+

#else

1733+

mrb_int_overflow(mrb, "round");

1734+

#endif

1735+

}

1736+

}

1737+

a = c;

1738+

}

16941739

return mrb_int_value(mrb, a);

16951740

}

16961741

@@ -1714,21 +1759,16 @@ int_truncate(mrb_state *mrb, mrb_value x)

17141759

#ifdef MRB_USE_BIGINT

17151760

if (mrb_bigint_p(x)) {

17161761

mrb_value m = mrb_bint_mod(mrb, x, f);

1762+

x = mrb_bint_sub_d(mrb, x, m);

17171763

if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) < 0) {

1718-

return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, m));

1719-

}

1720-

else {

1721-

return mrb_bint_sub(mrb, x, m);

1764+

return mrb_bint_add(mrb, x, f);

17221765

}

1766+

return x;

17231767

}

17241768

#endif

17251769

mrb_int a = mrb_integer(x);

17261770

mrb_int b = mrb_integer(f);

1727-

int neg = a < 0;

1728-

if (neg) a = -a;

1729-

a = a / b * b;

1730-

if (neg) a = -a;

1731-

return mrb_int_value(mrb, a);

1771+

return mrb_int_value(mrb, a - (a % b));

17321772

}

1733177317341774

/* 15.2.8.3.23 */

Read the original on github.com ↗