diff options
| author | Paul Eggert | 2019-01-06 16:23:41 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-01-06 16:25:40 -0800 |
| commit | 202bd7bff2710b98cde4ae4b6e1f6de9818591f8 (patch) | |
| tree | 5b58e9df997c158ccd6887a1c5ac81533040744f /src/floatfns.c | |
| parent | b0b483d714e87ee0a4572f9c541514a1ac1a8226 (diff) | |
| download | emacs-202bd7bff2710b98cde4ae4b6e1f6de9818591f8.tar.gz emacs-202bd7bff2710b98cde4ae4b6e1f6de9818591f8.zip | |
Fix logb on zero, infinite, NaN args
Change logb to return -infinity, +infinity, and NaN respectively.
Formerly logb returned an extreme fixnum to represent
infinity, but this is no longer the right thing to do now that
we have bignums and there is no extreme integer.
* doc/lispref/numbers.texi (Float Basics), etc/NEWS: Document.
* src/floatfns.c (Flogb): Implement this.
Diffstat (limited to 'src/floatfns.c')
| -rw-r--r-- | src/floatfns.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index 2d76b97eec7..a913aad5aac 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -306,27 +306,22 @@ This is the same as the exponent of a float. */) | |||
| 306 | if (FLOATP (arg)) | 306 | if (FLOATP (arg)) |
| 307 | { | 307 | { |
| 308 | double f = XFLOAT_DATA (arg); | 308 | double f = XFLOAT_DATA (arg); |
| 309 | |||
| 310 | if (f == 0) | 309 | if (f == 0) |
| 311 | value = MOST_NEGATIVE_FIXNUM; | 310 | return make_float (-HUGE_VAL); |
| 312 | else if (isfinite (f)) | 311 | if (!isfinite (f)) |
| 313 | { | 312 | return f < 0 ? make_float (-f) : arg; |
| 314 | int ivalue; | 313 | int ivalue; |
| 315 | frexp (f, &ivalue); | 314 | frexp (f, &ivalue); |
| 316 | value = ivalue - 1; | 315 | value = ivalue - 1; |
| 317 | } | ||
| 318 | else | ||
| 319 | value = MOST_POSITIVE_FIXNUM; | ||
| 320 | } | 316 | } |
| 321 | else if (BIGNUMP (arg)) | 317 | else if (!FIXNUMP (arg)) |
| 322 | value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1; | 318 | value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1; |
| 323 | else | 319 | else |
| 324 | { | 320 | { |
| 325 | eassert (FIXNUMP (arg)); | 321 | EMACS_INT i = XFIXNUM (arg); |
| 326 | EMACS_INT i = eabs (XFIXNUM (arg)); | 322 | if (i == 0) |
| 327 | value = (i == 0 | 323 | return make_float (-HUGE_VAL); |
| 328 | ? MOST_NEGATIVE_FIXNUM | 324 | value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i)); |
| 329 | : EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (i)); | ||
| 330 | } | 325 | } |
| 331 | 326 | ||
| 332 | return make_fixnum (value); | 327 | return make_fixnum (value); |