diff options
| author | Paul Eggert | 2018-09-04 11:49:41 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-09-04 11:50:54 -0700 |
| commit | 21637d5e5b29d5ec8fb966c0ddfbfba3eb33da38 (patch) | |
| tree | e0d7a0b9edac17b7fd6f7dc876e1ed97082dae0e | |
| parent | 628f6a2c7a9fe476b7e71efed3a8f8784a00cc54 (diff) | |
| download | emacs-21637d5e5b29d5ec8fb966c0ddfbfba3eb33da38.tar.gz emacs-21637d5e5b29d5ec8fb966c0ddfbfba3eb33da38.zip | |
Fix (round FLOAT BIGNUM) bug
* src/floatfns.c (rounding_driver): Fix bug when one
argument is a float and the other is a bignum.
* test/src/floatfns-tests.el (bignum-round): Test for the bug.
| -rw-r--r-- | src/floatfns.c | 7 | ||||
| -rw-r--r-- | test/src/floatfns-tests.el | 5 |
2 files changed, 10 insertions, 2 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index 2f33b8652b2..13ab7b0359f 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -355,6 +355,8 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor, | |||
| 355 | CHECK_NUMBER (divisor); | 355 | CHECK_NUMBER (divisor); |
| 356 | if (!FLOATP (arg) && !FLOATP (divisor)) | 356 | if (!FLOATP (arg) && !FLOATP (divisor)) |
| 357 | { | 357 | { |
| 358 | /* Divide as integers. Converting to double might lose | ||
| 359 | info, even for fixnums; also see the FIXME below. */ | ||
| 358 | if (EQ (divisor, make_fixnum (0))) | 360 | if (EQ (divisor, make_fixnum (0))) |
| 359 | xsignal0 (Qarith_error); | 361 | xsignal0 (Qarith_error); |
| 360 | int_divide (mpz[0], | 362 | int_divide (mpz[0], |
| @@ -363,10 +365,11 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor, | |||
| 363 | return make_integer_mpz (); | 365 | return make_integer_mpz (); |
| 364 | } | 366 | } |
| 365 | 367 | ||
| 366 | double f1 = FLOATP (arg) ? XFLOAT_DATA (arg) : XFIXNUM (arg); | 368 | double f1 = XFLOATINT (arg); |
| 367 | double f2 = FLOATP (divisor) ? XFLOAT_DATA (divisor) : XFIXNUM (divisor); | 369 | double f2 = XFLOATINT (divisor); |
| 368 | if (! IEEE_FLOATING_POINT && f2 == 0) | 370 | if (! IEEE_FLOATING_POINT && f2 == 0) |
| 369 | xsignal0 (Qarith_error); | 371 | xsignal0 (Qarith_error); |
| 372 | /* FIXME: This division rounds, so the result is double-rounded. */ | ||
| 370 | d = f1 / f2; | 373 | d = f1 / f2; |
| 371 | } | 374 | } |
| 372 | 375 | ||
diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el index d41b08f7965..9a382058b43 100644 --- a/test/src/floatfns-tests.el +++ b/test/src/floatfns-tests.el | |||
| @@ -70,6 +70,11 @@ | |||
| 70 | (should (= n (floor n))) | 70 | (should (= n (floor n))) |
| 71 | (should (= n (round n))) | 71 | (should (= n (round n))) |
| 72 | (should (= n (truncate n))) | 72 | (should (= n (truncate n))) |
| 73 | (let ((-n (- n)) | ||
| 74 | (f (float n)) | ||
| 75 | (-f (- (float n)))) | ||
| 76 | (should (= 1 (round n f) (round -n -f) (round f n) (round -f -n))) | ||
| 77 | (should (= -1 (round -n f) (round n -f) (round f -n) (round -f n)))) | ||
| 73 | (dolist (d ns) | 78 | (dolist (d ns) |
| 74 | (let ((q (/ n d)) | 79 | (let ((q (/ n d)) |
| 75 | (r (% n d)) | 80 | (r (% n d)) |