@@ -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}
17331773
17341774/* 15.2.8.3.23 */
0 commit comments