comparison src/floatfns.c @ 4717:fcc7e89d5e68

Properly handle continuable divide-by-zero errors. Fix truncation of a zero-valued ratio. See xemacs-patches message <870180fe0910080956h5d674f03q185d11aa6fc57bd2@mail.gmail.com>.
author Jerry James <james@xemacs.org>
date Mon, 12 Oct 2009 12:10:04 -0600
parents b5e1d4f6b66f
children f31c12360354 e0db3c197671
comparison
equal deleted inserted replaced
4716:dca5bb2adff1 4717:fcc7e89d5e68
106 #endif 106 #endif
107 107
108 108
109 #define arith_error(op,arg) \ 109 #define arith_error(op,arg) \
110 Fsignal (Qarith_error, list2 (build_msg_string (op), arg)) 110 Fsignal (Qarith_error, list2 (build_msg_string (op), arg))
111 #define arith_error2(op,a1,a2) \
112 Fsignal (Qarith_error, list3 (build_msg_string (op), a1, a2))
111 #define range_error(op,arg) \ 113 #define range_error(op,arg) \
112 Fsignal (Qrange_error, list2 (build_msg_string (op), arg)) 114 Fsignal (Qrange_error, list2 (build_msg_string (op), arg))
113 #define range_error2(op,a1,a2) \ 115 #define range_error2(op,a1,a2) \
114 Fsignal (Qrange_error, list3 (build_msg_string (op), a1, a2)) 116 Fsignal (Qrange_error, list3 (build_msg_string (op), a1, a2))
115 #define domain_error(op,arg) \ 117 #define domain_error(op,arg) \
887 RATIO, return_float); \ 889 RATIO, return_float); \
888 MAYBE_ONE_ARG_WITH_NUMBER_TYPES (conversion, \ 890 MAYBE_ONE_ARG_WITH_NUMBER_TYPES (conversion, \
889 BIGFLOAT, return_float); \ 891 BIGFLOAT, return_float); \
890 return conversion##_one_mundane_arg (number, divisor, \ 892 return conversion##_one_mundane_arg (number, divisor, \
891 return_float) 893 return_float)
892
893 894
894 #define CONVERT_WITHOUT_NUMBER_TYPES(conversion, return_float) \ 895 #define CONVERT_WITHOUT_NUMBER_TYPES(conversion, return_float) \
895 if (!NILP (divisor)) \ 896 if (!NILP (divisor)) \
896 { \ 897 { \
897 /* The promote_args call if number types are available \ 898 /* The promote_args call if number types are available \
941 case BIGNUM_T: \ 942 case BIGNUM_T: \
942 return conversion##_two_bignum (number, divisor, return_float) 943 return conversion##_two_bignum (number, divisor, return_float)
943 944
944 #define MAYBE_ONE_ARG_BIGNUM(converse, return_float) \ 945 #define MAYBE_ONE_ARG_BIGNUM(converse, return_float) \
945 if (BIGNUM_P (number)) \ 946 if (BIGNUM_P (number)) \
946 return conversion##_one_bignum (number, divisor, return_float) 947 return conversion##_one_bignum (number, divisor, return_float)
947 #else 948 #else
948 #define MAYBE_TWO_ARGS_BIGNUM(conversion, return_float) 949 #define MAYBE_TWO_ARGS_BIGNUM(conversion, return_float)
949 #define MAYBE_ONE_ARG_BIGNUM(converse, return_float) 950 #define MAYBE_ONE_ARG_BIGNUM(converse, return_float)
950 #endif 951 #endif
951 952
952 #ifdef HAVE_RATIO 953 #ifdef HAVE_RATIO
953 #define MAYBE_TWO_ARGS_RATIO(conversion, return_float) \ 954 #define MAYBE_TWO_ARGS_RATIO(conversion, return_float) \
954 case RATIO_T: \ 955 case RATIO_T: \
955 return conversion##_two_ratio (number, divisor, return_float) 956 return conversion##_two_ratio (number, divisor, return_float)
956 957
957 #define MAYBE_ONE_ARG_RATIO(conversion, return_float) \ 958 #define MAYBE_ONE_ARG_RATIO(conversion, return_float) \
958 if (RATIOP (number)) \ 959 if (RATIOP (number)) \
959 return conversion##_one_ratio (number, divisor, return_float) 960 return conversion##_one_ratio (number, divisor, return_float)
960 #else 961 #else
961 #define MAYBE_TWO_ARGS_RATIO(conversion, return_float) 962 #define MAYBE_TWO_ARGS_RATIO(conversion, return_float)
962 #define MAYBE_ONE_ARG_RATIO(converse, return_float) 963 #define MAYBE_ONE_ARG_RATIO(converse, return_float)
963 #endif 964 #endif
964 965
965 #ifdef HAVE_BIGFLOAT 966 #ifdef HAVE_BIGFLOAT
966 #define MAYBE_TWO_ARGS_BIGFLOAT(conversion, return_float) \ 967 #define MAYBE_TWO_ARGS_BIGFLOAT(conversion, return_float) \
967 case BIGFLOAT_T: \ 968 case BIGFLOAT_T: \
968 return conversion##_two_bigfloat (number, divisor, return_float) 969 return conversion##_two_bigfloat (number, divisor, return_float)
969 970
970 #define MAYBE_ONE_ARG_BIGFLOAT(conversion, return_float) \ 971 #define MAYBE_ONE_ARG_BIGFLOAT(conversion, return_float) \
971 if (BIGFLOATP (number)) \ 972 if (BIGFLOATP (number)) \
972 return conversion##_one_bigfloat (number, divisor, return_float) 973 return conversion##_one_bigfloat (number, divisor, return_float)
973 #else 974 #else
974 #define MAYBE_TWO_ARGS_BIGFLOAT(conversion, return_float) 975 #define MAYBE_TWO_ARGS_BIGFLOAT(conversion, return_float)
975 #define MAYBE_ONE_ARG_BIGFLOAT(converse, return_float) 976 #define MAYBE_ONE_ARG_BIGFLOAT(converse, return_float)
976 #endif 977 #endif
977 978
978 #define MAYBE_TWO_ARGS_WITH_NUMBER_TYPES(convers, upcase, return_float) \ 979 #define MAYBE_TWO_ARGS_WITH_NUMBER_TYPES(convers, upcase, return_float) \
979 MAYBE_TWO_ARGS_##upcase(convers, return_float) 980 MAYBE_TWO_ARGS_##upcase(convers, return_float)
980 981
1013 EMACS_INT i1 = XREALINT (number); 1014 EMACS_INT i1 = XREALINT (number);
1014 EMACS_INT i2 = XREALINT (divisor); 1015 EMACS_INT i2 = XREALINT (divisor);
1015 EMACS_INT i3 = 0, i4 = 0; 1016 EMACS_INT i3 = 0, i4 = 0;
1016 1017
1017 if (i2 == 0) 1018 if (i2 == 0)
1018 Fsignal (Qarith_error, Qnil); 1019 return arith_error2 ("ceiling", number, divisor);
1019 1020
1020 /* With C89's integer /, the result is implementation-defined if either 1021 /* With C89's integer /, the result is implementation-defined if either
1021 operand is negative, so use only nonnegative operands. Here we do 1022 operand is negative, so use only nonnegative operands. Here we do
1022 basically the opposite of what floor_two_fixnum does, we add one in the 1023 basically the opposite of what floor_two_fixnum does, we add one in the
1023 non-negative case: */ 1024 non-negative case: */
1078 int return_float) 1079 int return_float)
1079 { 1080 {
1080 Lisp_Object res0, res1; 1081 Lisp_Object res0, res1;
1081 1082
1082 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0) 1083 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0)
1083 { 1084 return arith_error2 ("ceiling", number, divisor);
1084 Fsignal (Qarith_error, Qnil);
1085 }
1086 1085
1087 bignum_ceil (scratch_bignum, XBIGNUM_DATA (number), XBIGNUM_DATA (divisor)); 1086 bignum_ceil (scratch_bignum, XBIGNUM_DATA (number), XBIGNUM_DATA (divisor));
1088 1087
1089 res0 = return_float ? make_float (bignum_to_double (scratch_bignum)) : 1088 res0 = return_float ? make_float (bignum_to_double (scratch_bignum)) :
1090 Fcanonicalize_number (make_bignum_bg (scratch_bignum)); 1089 Fcanonicalize_number (make_bignum_bg (scratch_bignum));
1110 int return_float) 1109 int return_float)
1111 { 1110 {
1112 Lisp_Object res0, res1; 1111 Lisp_Object res0, res1;
1113 1112
1114 if (ratio_sign (XRATIO_DATA (divisor)) == 0) 1113 if (ratio_sign (XRATIO_DATA (divisor)) == 0)
1115 { 1114 return arith_error2 ("ceiling", number, divisor);
1116 Fsignal (Qarith_error, Qnil);
1117 }
1118 1115
1119 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor)); 1116 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor));
1120 1117
1121 bignum_ceil (scratch_bignum, ratio_numerator (scratch_ratio), 1118 bignum_ceil (scratch_bignum, ratio_numerator (scratch_ratio),
1122 ratio_denominator (scratch_ratio)); 1119 ratio_denominator (scratch_ratio));
1147 int return_float) 1144 int return_float)
1148 { 1145 {
1149 Lisp_Object res0; 1146 Lisp_Object res0;
1150 1147
1151 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0) 1148 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0)
1152 { 1149 return arith_error2 ("ceiling", number, divisor);
1153 Fsignal (Qarith_error, Qnil);
1154 }
1155 1150
1156 bigfloat_set_prec (scratch_bigfloat, max (XBIGFLOAT_GET_PREC (number), 1151 bigfloat_set_prec (scratch_bigfloat, max (XBIGFLOAT_GET_PREC (number),
1157 XBIGFLOAT_GET_PREC (divisor))); 1152 XBIGFLOAT_GET_PREC (divisor)));
1158 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number), 1153 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number),
1159 XBIGFLOAT_DATA (divisor)); 1154 XBIGFLOAT_DATA (divisor));
1246 { 1241 {
1247 double f1 = extract_float (number); 1242 double f1 = extract_float (number);
1248 double f2 = extract_float (divisor); 1243 double f2 = extract_float (divisor);
1249 double f0, remain; 1244 double f0, remain;
1250 Lisp_Object res0; 1245 Lisp_Object res0;
1251 1246
1252 if (f2 == 0.0) 1247 if (f2 == 0.0)
1253 { 1248 return arith_error2 ("ceiling", number, divisor);
1254 Fsignal (Qarith_error, Qnil); 1249
1255 }
1256
1257 IN_FLOAT2 (f0 = ceil (f1 / f2), MAYBE_EFF("ceiling"), number, divisor); 1250 IN_FLOAT2 (f0 = ceil (f1 / f2), MAYBE_EFF("ceiling"), number, divisor);
1258 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF("ceiling"), number, divisor); 1251 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF("ceiling"), number, divisor);
1259 1252
1260 if (return_float) 1253 if (return_float)
1261 { 1254 {
1304 return values2 (make_float ((double) XINT (number)), Qzero); 1297 return values2 (make_float ((double) XINT (number)), Qzero);
1305 } 1298 }
1306 #ifdef HAVE_BIGNUM 1299 #ifdef HAVE_BIGNUM
1307 else if (BIGNUMP (number)) 1300 else if (BIGNUMP (number))
1308 { 1301 {
1309 return values2 (make_float 1302 return values2 (make_float
1310 (bignum_to_double (XBIGNUM_DATA (number))), 1303 (bignum_to_double (XBIGNUM_DATA (number))),
1311 Qzero); 1304 Qzero);
1312 } 1305 }
1313 #endif 1306 #endif
1314 } 1307 }
1321 #endif 1314 #endif
1322 { 1315 {
1323 return values2 (number, Qzero); 1316 return values2 (number, Qzero);
1324 } 1317 }
1325 } 1318 }
1326 1319
1327 MAYBE_CHAR_OR_MARKER (ceiling); 1320 MAYBE_CHAR_OR_MARKER (ceiling);
1328 1321
1329 return Ffceiling (wrong_type_argument (Qnumberp, number), divisor); 1322 return Ffceiling (wrong_type_argument (Qnumberp, number), divisor);
1330 } 1323 }
1331 1324
1337 EMACS_INT i2 = XREALINT (divisor); 1330 EMACS_INT i2 = XREALINT (divisor);
1338 EMACS_INT i3 = 0, i4 = 0; 1331 EMACS_INT i3 = 0, i4 = 0;
1339 Lisp_Object res0; 1332 Lisp_Object res0;
1340 1333
1341 if (i2 == 0) 1334 if (i2 == 0)
1342 { 1335 return arith_error2 ("floor", number, divisor);
1343 Fsignal (Qarith_error, Qnil);
1344 }
1345 1336
1346 /* With C89's integer /, the result is implementation-defined if either 1337 /* With C89's integer /, the result is implementation-defined if either
1347 operand is negative, so use only nonnegative operands. Notice also that 1338 operand is negative, so use only nonnegative operands. Notice also that
1348 we're forcing the quotient of any negative numbers towards minus 1339 we're forcing the quotient of any negative numbers towards minus
1349 infinity. */ 1340 infinity. */
1371 int return_float) 1362 int return_float)
1372 { 1363 {
1373 Lisp_Object res0, res1; 1364 Lisp_Object res0, res1;
1374 1365
1375 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0) 1366 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0)
1376 { 1367 return arith_error2 ("floor", number, divisor);
1377 Fsignal (Qarith_error, Qnil);
1378 }
1379 1368
1380 bignum_floor (scratch_bignum, XBIGNUM_DATA (number), 1369 bignum_floor (scratch_bignum, XBIGNUM_DATA (number),
1381 XBIGNUM_DATA (divisor)); 1370 XBIGNUM_DATA (divisor));
1382 1371
1383 if (return_float) 1372 if (return_float)
1410 int return_float) 1399 int return_float)
1411 { 1400 {
1412 Lisp_Object res0, res1; 1401 Lisp_Object res0, res1;
1413 1402
1414 if (ratio_sign (XRATIO_DATA (divisor)) == 0) 1403 if (ratio_sign (XRATIO_DATA (divisor)) == 0)
1415 { 1404 return arith_error2 ("floor", number, divisor);
1416 Fsignal (Qarith_error, Qnil);
1417 }
1418 1405
1419 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor)); 1406 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor));
1420 1407
1421 bignum_floor (scratch_bignum, ratio_numerator (scratch_ratio), 1408 bignum_floor (scratch_bignum, ratio_numerator (scratch_ratio),
1422 ratio_denominator (scratch_ratio)); 1409 ratio_denominator (scratch_ratio));
1447 int return_float) 1434 int return_float)
1448 { 1435 {
1449 Lisp_Object res0; 1436 Lisp_Object res0;
1450 1437
1451 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0) 1438 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0)
1452 { 1439 return arith_error2 ("floor", number, divisor);
1453 Fsignal (Qarith_error, Qnil);
1454 }
1455 1440
1456 bigfloat_set_prec (scratch_bigfloat, max (XBIGFLOAT_GET_PREC (number), 1441 bigfloat_set_prec (scratch_bigfloat, max (XBIGFLOAT_GET_PREC (number),
1457 XBIGFLOAT_GET_PREC (divisor))); 1442 XBIGFLOAT_GET_PREC (divisor)));
1458 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number), 1443 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number),
1459 XBIGFLOAT_DATA (divisor)); 1444 XBIGFLOAT_DATA (divisor));
1544 int return_float) 1529 int return_float)
1545 { 1530 {
1546 double f1 = extract_float (number); 1531 double f1 = extract_float (number);
1547 double f2 = extract_float (divisor); 1532 double f2 = extract_float (divisor);
1548 double f0, remain; 1533 double f0, remain;
1549 1534
1550 if (f2 == 0.0) 1535 if (f2 == 0.0)
1551 { 1536 return arith_error2 ("floor", number, divisor);
1552 Fsignal (Qarith_error, Qnil); 1537
1553 }
1554
1555 IN_FLOAT2 (f0 = floor (f1 / f2), MAYBE_EFF ("floor"), number, divisor); 1538 IN_FLOAT2 (f0 = floor (f1 / f2), MAYBE_EFF ("floor"), number, divisor);
1556 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("floor"), number, divisor); 1539 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("floor"), number, divisor);
1557 1540
1558 if (return_float) 1541 if (return_float)
1559 { 1542 {
1619 } 1602 }
1620 1603
1621 /* Algorithm taken from cl-extra.el, now to be found as cl-round in 1604 /* Algorithm taken from cl-extra.el, now to be found as cl-round in
1622 tests/automated/lisp-tests.el. */ 1605 tests/automated/lisp-tests.el. */
1623 static Lisp_Object 1606 static Lisp_Object
1624 round_two_fixnum (Lisp_Object number, Lisp_Object divisor, 1607 round_two_fixnum (Lisp_Object number, Lisp_Object divisor, int return_float)
1625 int return_float)
1626 { 1608 {
1627 EMACS_INT i1 = XREALINT (number); 1609 EMACS_INT i1 = XREALINT (number);
1628 EMACS_INT i2 = XREALINT (divisor); 1610 EMACS_INT i2 = XREALINT (divisor);
1629 EMACS_INT i0, hi2, flooring, floored, flsecond; 1611 EMACS_INT i0, hi2, flooring, floored, flsecond;
1630 1612
1631 if (i2 == 0) 1613 if (i2 == 0)
1632 { 1614 return arith_error2 ("round", number, divisor);
1633 Fsignal (Qarith_error, Qnil);
1634 }
1635 1615
1636 hi2 = i2 < 0 ? -( -i2 / 2) : i2 / 2; 1616 hi2 = i2 < 0 ? -( -i2 / 2) : i2 / 2;
1637 1617
1638 flooring = hi2 + i1; 1618 flooring = hi2 + i1;
1639 1619
1714 *remain = make_bignum_bg (scratch_bignum); 1694 *remain = make_bignum_bg (scratch_bignum);
1715 } 1695 }
1716 } 1696 }
1717 1697
1718 static Lisp_Object 1698 static Lisp_Object
1719 round_two_bignum (Lisp_Object number, Lisp_Object divisor, 1699 round_two_bignum (Lisp_Object number, Lisp_Object divisor, int return_float)
1720 int return_float)
1721 { 1700 {
1722 Lisp_Object res0, res1; 1701 Lisp_Object res0, res1;
1723 1702
1724 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0) 1703 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0)
1725 { 1704 return arith_error2 ("round", number, divisor);
1726 Fsignal (Qarith_error, Qnil);
1727 }
1728 1705
1729 round_two_bignum_1 (XBIGNUM_DATA (number), XBIGNUM_DATA (divisor), 1706 round_two_bignum_1 (XBIGNUM_DATA (number), XBIGNUM_DATA (divisor),
1730 &res0, &res1); 1707 &res0, &res1);
1731 1708
1732 if (return_float) 1709 if (return_float)
1748 int return_float) 1725 int return_float)
1749 { 1726 {
1750 Lisp_Object res0, res1; 1727 Lisp_Object res0, res1;
1751 1728
1752 if (ratio_sign (XRATIO_DATA (divisor)) == 0) 1729 if (ratio_sign (XRATIO_DATA (divisor)) == 0)
1753 { 1730 return arith_error2 ("round", number, divisor);
1754 Fsignal (Qarith_error, Qnil);
1755 }
1756 1731
1757 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor)); 1732 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor));
1758 1733
1759 round_two_bignum_1 (ratio_numerator (scratch_ratio), 1734 round_two_bignum_1 (ratio_numerator (scratch_ratio),
1760 ratio_denominator (scratch_ratio), &res0, &res1); 1735 ratio_denominator (scratch_ratio), &res0, &res1);
1761 1736
1762 if (!ZEROP (res1)) 1737 if (!ZEROP (res1))
1763 { 1738 {
1764 /* The numerator and denominator don't round exactly, calculate a 1739 /* The numerator and denominator don't round exactly, calculate a
1765 ratio remainder: */ 1740 ratio remainder: */
1766 ratio_set_bignum (scratch_ratio2, XBIGNUM_DATA (res0)); 1741 ratio_set_bignum (scratch_ratio2, XBIGNUM_DATA (res0));
1767 ratio_mul (scratch_ratio, scratch_ratio2, XRATIO_DATA (divisor)); 1742 ratio_mul (scratch_ratio, scratch_ratio2, XRATIO_DATA (divisor));
1768 ratio_sub (scratch_ratio, XRATIO_DATA (number), scratch_ratio); 1743 ratio_sub (scratch_ratio, XRATIO_DATA (number), scratch_ratio);
1769 1744
1770 res1 = Fcanonicalize_number (make_ratio_rt (scratch_ratio)); 1745 res1 = Fcanonicalize_number (make_ratio_rt (scratch_ratio));
1771 } 1746 }
1772 1747
1773 res0 = return_float ? 1748 res0 = return_float ?
1774 make_float ((double)bignum_to_double(XBIGNUM_DATA (res0))) : 1749 make_float ((double)bignum_to_double(XBIGNUM_DATA (res0))) :
1851 1826
1852 unsigned long prec = max (XBIGFLOAT_GET_PREC (number), 1827 unsigned long prec = max (XBIGFLOAT_GET_PREC (number),
1853 XBIGFLOAT_GET_PREC (divisor)); 1828 XBIGFLOAT_GET_PREC (divisor));
1854 1829
1855 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0) 1830 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0)
1856 { 1831 return arith_error2 ("round", number, divisor);
1857 Fsignal (Qarith_error, Qnil);
1858 }
1859 1832
1860 bigfloat_init (divided); 1833 bigfloat_init (divided);
1861 bigfloat_set_prec (divided, prec); 1834 bigfloat_set_prec (divided, prec);
1862 1835
1863 bigfloat_div (divided, XBIGFLOAT_DATA (number), XBIGFLOAT_DATA (divisor)); 1836 bigfloat_div (divided, XBIGFLOAT_DATA (number), XBIGFLOAT_DATA (divisor));
1864 1837
1865 res0 = round_one_bigfloat_1 (divided); 1838 res0 = round_one_bigfloat_1 (divided);
1866 1839
1867 bigfloat_set_prec (scratch_bigfloat, prec); 1840 bigfloat_set_prec (scratch_bigfloat, prec);
1868 bigfloat_set_prec (scratch_bigfloat2, prec); 1841 bigfloat_set_prec (scratch_bigfloat2, prec);
1869 1842
1870 bigfloat_mul (scratch_bigfloat, XBIGFLOAT_DATA (res0), 1843 bigfloat_mul (scratch_bigfloat, XBIGFLOAT_DATA (res0),
1871 XBIGFLOAT_DATA (divisor)); 1844 XBIGFLOAT_DATA (divisor));
1872 bigfloat_sub (scratch_bigfloat2, XBIGFLOAT_DATA (number), 1845 bigfloat_sub (scratch_bigfloat2, XBIGFLOAT_DATA (number),
1873 scratch_bigfloat); 1846 scratch_bigfloat);
1874 1847
1919 int return_float) 1892 int return_float)
1920 { 1893 {
1921 Lisp_Object res0 = round_one_bigfloat_1 (XBIGFLOAT_DATA (number)); 1894 Lisp_Object res0 = round_one_bigfloat_1 (XBIGFLOAT_DATA (number));
1922 Lisp_Object res1; 1895 Lisp_Object res1;
1923 1896
1924 bigfloat_sub (scratch_bigfloat, XBIGFLOAT_DATA (number), 1897 bigfloat_sub (scratch_bigfloat, XBIGFLOAT_DATA (number),
1925 XBIGFLOAT_DATA (res0)); 1898 XBIGFLOAT_DATA (res0));
1926 1899
1927 res1 = make_bigfloat_bf (scratch_bigfloat); 1900 res1 = make_bigfloat_bf (scratch_bigfloat);
1928 1901
1929 if (!return_float) 1902 if (!return_float)
1946 int return_float) 1919 int return_float)
1947 { 1920 {
1948 double f1 = extract_float (number); 1921 double f1 = extract_float (number);
1949 double f2 = extract_float (divisor); 1922 double f2 = extract_float (divisor);
1950 double f0, remain; 1923 double f0, remain;
1951 1924
1952 if (f2 == 0.0) 1925 if (f2 == 0.0)
1953 Fsignal (Qarith_error, Qnil); 1926 return arith_error2 ("round", number, divisor);
1954 1927
1955 IN_FLOAT2 ((f0 = emacs_rint (f1 / f2)), MAYBE_EFF ("round"), number, 1928 IN_FLOAT2 ((f0 = emacs_rint (f1 / f2)), MAYBE_EFF ("round"), number,
1956 divisor); 1929 divisor);
1957 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("round"), number, divisor); 1930 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("round"), number, divisor);
1958 1931
1959 if (return_float) 1932 if (return_float)
1960 { 1933 {
1961 return values2 (make_float (f0), make_float (remain)); 1934 return values2 (make_float (f0), make_float (remain));
1971 round_one_float (Lisp_Object number, int return_float) 1944 round_one_float (Lisp_Object number, int return_float)
1972 { 1945 {
1973 double d; 1946 double d;
1974 /* Screw the prevailing rounding mode. */ 1947 /* Screw the prevailing rounding mode. */
1975 IN_FLOAT ((d = emacs_rint (XFLOAT_DATA (number))), MAYBE_EFF ("round"), 1948 IN_FLOAT ((d = emacs_rint (XFLOAT_DATA (number))), MAYBE_EFF ("round"),
1976 number); 1949 number);
1977 1950
1978 if (return_float) 1951 if (return_float)
1979 { 1952 {
1980 return values2 (make_float (d), make_float (XFLOAT_DATA (number) - d)); 1953 return values2 (make_float (d), make_float (XFLOAT_DATA (number) - d));
1981 } 1954 }
1982 else 1955 else
1983 { 1956 {
1984 return values2 ((float_to_int (d, MAYBE_EFF ("round"), number, 1957 return values2 ((float_to_int (d, MAYBE_EFF ("round"), number,
1985 Qunbound)), 1958 Qunbound)),
1986 make_float (XFLOAT_DATA (number) - d)); 1959 make_float (XFLOAT_DATA (number) - d));
1987 } 1960 }
1988 } 1961 }
1989 1962
1990 EXFUN (Fround, 2); 1963 EXFUN (Fround, 2);
2012 1985
2013 MAYBE_CHAR_OR_MARKER (round); 1986 MAYBE_CHAR_OR_MARKER (round);
2014 1987
2015 if (return_float) 1988 if (return_float)
2016 { 1989 {
2017 return Ffround (wrong_type_argument (Qnumberp, number), divisor); 1990 return Ffround (wrong_type_argument (Qnumberp, number), divisor);
2018 } 1991 }
2019 else 1992 else
2020 { 1993 {
2021 return Fround (wrong_type_argument (Qnumberp, number), divisor); 1994 return Fround (wrong_type_argument (Qnumberp, number), divisor);
2022 } 1995 }
2023 } 1996 }
2024 1997
2025 static Lisp_Object 1998 static Lisp_Object
2026 truncate_two_fixnum (Lisp_Object number, Lisp_Object divisor, 1999 truncate_two_fixnum (Lisp_Object number, Lisp_Object divisor,
2029 EMACS_INT i1 = XREALINT (number); 2002 EMACS_INT i1 = XREALINT (number);
2030 EMACS_INT i2 = XREALINT (divisor); 2003 EMACS_INT i2 = XREALINT (divisor);
2031 EMACS_INT i0; 2004 EMACS_INT i0;
2032 2005
2033 if (i2 == 0) 2006 if (i2 == 0)
2034 Fsignal (Qarith_error, Qnil); 2007 return arith_error2 ("truncate", number, divisor);
2035 2008
2036 /* We're truncating towards zero, so apart from avoiding the C89 2009 /* We're truncating towards zero, so apart from avoiding the C89
2037 implementation-defined behaviour with truncation and negative numbers, 2010 implementation-defined behaviour with truncation and negative numbers,
2038 we don't need to do anything further: */ 2011 we don't need to do anything further: */
2039 i0 = (i2 < 0 2012 i0 = (i2 < 0
2056 int return_float) 2029 int return_float)
2057 { 2030 {
2058 Lisp_Object res0; 2031 Lisp_Object res0;
2059 2032
2060 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0) 2033 if (bignum_sign (XBIGNUM_DATA (divisor)) == 0)
2061 { 2034 return arith_error2 ("truncate", number, divisor);
2062 Fsignal (Qarith_error, Qnil);
2063 }
2064 2035
2065 bignum_div (scratch_bignum, XBIGNUM_DATA (number), 2036 bignum_div (scratch_bignum, XBIGNUM_DATA (number),
2066 XBIGNUM_DATA (divisor)); 2037 XBIGNUM_DATA (divisor));
2067 2038
2068 if (return_float) 2039 if (return_float)
2094 int return_float) 2065 int return_float)
2095 { 2066 {
2096 Lisp_Object res0; 2067 Lisp_Object res0;
2097 2068
2098 if (ratio_sign (XRATIO_DATA (divisor)) == 0) 2069 if (ratio_sign (XRATIO_DATA (divisor)) == 0)
2099 { 2070 return arith_error2 ("truncate", number, divisor);
2100 Fsignal (Qarith_error, Qnil);
2101 }
2102 2071
2103 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor)); 2072 ratio_div (scratch_ratio, XRATIO_DATA (number), XRATIO_DATA (divisor));
2104 2073
2105 bignum_div (scratch_bignum, ratio_numerator (scratch_ratio), 2074 bignum_div (scratch_bignum, ratio_numerator (scratch_ratio),
2106 ratio_denominator (scratch_ratio)); 2075 ratio_denominator (scratch_ratio));
2136 Lisp_Object res0; 2105 Lisp_Object res0;
2137 unsigned long prec = max (XBIGFLOAT_GET_PREC (number), 2106 unsigned long prec = max (XBIGFLOAT_GET_PREC (number),
2138 XBIGFLOAT_GET_PREC (divisor)); 2107 XBIGFLOAT_GET_PREC (divisor));
2139 2108
2140 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0) 2109 if (bigfloat_sign (XBIGFLOAT_DATA (divisor)) == 0)
2141 { 2110 return arith_error2 ("truncate", number, divisor);
2142 Fsignal (Qarith_error, Qnil);
2143 }
2144 2111
2145 bigfloat_set_prec (scratch_bigfloat, prec); 2112 bigfloat_set_prec (scratch_bigfloat, prec);
2146 bigfloat_set_prec (scratch_bigfloat2, prec); 2113 bigfloat_set_prec (scratch_bigfloat2, prec);
2147 2114
2148 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number), 2115 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (number),
2160 res0 = Fcanonicalize_number (make_bignum_bg (scratch_bignum)); 2127 res0 = Fcanonicalize_number (make_bignum_bg (scratch_bignum));
2161 #else 2128 #else
2162 res0 = make_int ((EMACS_INT) bigfloat_to_long (scratch_bigfloat)); 2129 res0 = make_int ((EMACS_INT) bigfloat_to_long (scratch_bigfloat));
2163 #endif /* HAVE_BIGNUM */ 2130 #endif /* HAVE_BIGNUM */
2164 } 2131 }
2165 2132
2166 bigfloat_mul (scratch_bigfloat2, scratch_bigfloat, XBIGFLOAT_DATA (divisor)); 2133 bigfloat_mul (scratch_bigfloat2, scratch_bigfloat, XBIGFLOAT_DATA (divisor));
2167 bigfloat_sub (scratch_bigfloat, XBIGFLOAT_DATA (number), scratch_bigfloat2); 2134 bigfloat_sub (scratch_bigfloat, XBIGFLOAT_DATA (number), scratch_bigfloat2);
2168 2135
2169 return values2 (res0, make_bigfloat_bf (scratch_bigfloat)); 2136 return values2 (res0, make_bigfloat_bf (scratch_bigfloat));
2170 } 2137 }
2176 int return_float) 2143 int return_float)
2177 { 2144 {
2178 Lisp_Object res0; 2145 Lisp_Object res0;
2179 2146
2180 if (ratio_sign (XRATIO_DATA (number)) == 0) 2147 if (ratio_sign (XRATIO_DATA (number)) == 0)
2181 { 2148 return Qzero;
2182 Fsignal (Qarith_error, Qnil);
2183 }
2184 2149
2185 bignum_div (scratch_bignum, XRATIO_NUMERATOR (number), 2150 bignum_div (scratch_bignum, XRATIO_NUMERATOR (number),
2186 XRATIO_DENOMINATOR (number)); 2151 XRATIO_DENOMINATOR (number));
2187 if (return_float) 2152 if (return_float)
2188 { 2153 {
2232 } 2197 }
2233 2198
2234 bigfloat_sub (scratch_bigfloat2, XBIGFLOAT_DATA (number), scratch_bigfloat); 2199 bigfloat_sub (scratch_bigfloat2, XBIGFLOAT_DATA (number), scratch_bigfloat);
2235 2200
2236 return 2201 return
2237 values2 (res0, 2202 values2 (res0,
2238 Fcanonicalize_number (make_bigfloat_bf (scratch_bigfloat2))); 2203 Fcanonicalize_number (make_bigfloat_bf (scratch_bigfloat2)));
2239 } 2204 }
2240 #endif /* HAVE_BIGFLOAT */ 2205 #endif /* HAVE_BIGFLOAT */
2241 2206
2242 static Lisp_Object 2207 static Lisp_Object
2245 { 2210 {
2246 double f1 = extract_float (number); 2211 double f1 = extract_float (number);
2247 double f2 = extract_float (divisor); 2212 double f2 = extract_float (divisor);
2248 double f0, remain; 2213 double f0, remain;
2249 Lisp_Object res0; 2214 Lisp_Object res0;
2250 2215
2251 if (f2 == 0.0) 2216 if (f2 == 0.0)
2252 { 2217 return arith_error2 ("truncate", number, divisor);
2253 Fsignal (Qarith_error, Qnil);
2254 }
2255 2218
2256 res0 = float_to_int (f1 / f2, MAYBE_EFF ("truncate"), number, Qunbound); 2219 res0 = float_to_int (f1 / f2, MAYBE_EFF ("truncate"), number, Qunbound);
2257 f0 = extract_float (res0); 2220 f0 = extract_float (res0);
2258 2221
2259 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("truncate"), number, divisor); 2222 IN_FLOAT2 (remain = f1 - (f0 * f2), MAYBE_EFF ("truncate"), number, divisor);
2323 2286
2324 DEFUN ("ceiling", Fceiling, 1, 2, 0, /* 2287 DEFUN ("ceiling", Fceiling, 1, 2, 0, /*
2325 Return the smallest integer no less than NUMBER. (Round toward +inf.) 2288 Return the smallest integer no less than NUMBER. (Round toward +inf.)
2326 2289
2327 With optional argument DIVISOR, return the smallest integer no less than 2290 With optional argument DIVISOR, return the smallest integer no less than
2328 the quotient of NUMBER and DIVISOR. 2291 the quotient of NUMBER and DIVISOR.
2329 2292
2330 This function returns multiple values; see `multiple-value-bind' and 2293 This function returns multiple values; see `multiple-value-bind' and
2331 `multiple-value-call'. The second returned value is the remainder in the 2294 `multiple-value-call'. The second returned value is the remainder in the
2332 calculation, which will be one minus the fractional part of NUMBER if DIVISOR 2295 calculation, which will be one minus the fractional part of NUMBER if DIVISOR
2333 is omitted or one. 2296 is omitted or one.