@@ -1611,16 +1611,26 @@ int_ceil(mrb_state *mrb, mrb_value x)
1611
1611
if (mrb_nil_p (f )) return x ;
1612
1612
#ifdef MRB_USE_BIGINT
1613
1613
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 ));
1615
1616
}
1616
1617
#endif
1617
1618
mrb_int a = mrb_integer (x );
1618
1619
mrb_int b = mrb_integer (f );
1620
+ mrb_int c = a % b ;
1619
1621
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
+ }
1624
1634
return mrb_int_value (mrb , a );
1625
1635
}
1626
1636
@@ -1648,10 +1658,20 @@ int_floor(mrb_state *mrb, mrb_value x)
1648
1658
#endif
1649
1659
mrb_int a = mrb_integer (x );
1650
1660
mrb_int b = mrb_integer (f );
1661
+ mrb_int c = a % b ;
1651
1662
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
+ }
1655
1675
return mrb_int_value (mrb , a );
1656
1676
}
1657
1677
@@ -1677,7 +1697,7 @@ int_round(mrb_state *mrb, mrb_value x)
1677
1697
mrb_value r = mrb_bint_mod (mrb , x , f );
1678
1698
mrb_value n = mrb_bint_sub (mrb , x , r );
1679
1699
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 ) ));
1681
1701
if ((cmp > 0 ) || (cmp == 0 && mrb_bint_cmp (mrb , x , mrb_fixnum_value (0 )) > 0 )) {
1682
1702
n = mrb_as_bint (mrb , n );
1683
1703
n = mrb_bint_add (mrb , n , f );
@@ -1687,10 +1707,35 @@ int_round(mrb_state *mrb, mrb_value x)
1687
1707
#endif
1688
1708
mrb_int a = mrb_integer (x );
1689
1709
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
+ }
1694
1739
return mrb_int_value (mrb , a );
1695
1740
}
1696
1741
@@ -1714,21 +1759,16 @@ int_truncate(mrb_state *mrb, mrb_value x)
1714
1759
#ifdef MRB_USE_BIGINT
1715
1760
if (mrb_bigint_p (x )) {
1716
1761
mrb_value m = mrb_bint_mod (mrb , x , f );
1762
+ x = mrb_bint_sub_d (mrb , x , m );
1717
1763
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 );
1722
1765
}
1766
+ return x ;
1723
1767
}
1724
1768
#endif
1725
1769
mrb_int a = mrb_integer (x );
1726
1770
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 ));
1732
1772
}
1733
1773
1734
1774
/* 15.2.8.3.23 */
0 commit comments