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.
This commit is contained in:
parent
b0b483d714
commit
202bd7bff2
3 changed files with 21 additions and 18 deletions
|
@ -313,14 +313,18 @@ and returns the result. @var{x1} and @var{x2} must be floating point.
|
|||
|
||||
@defun logb x
|
||||
This function returns the binary exponent of @var{x}. More
|
||||
precisely, the value is the logarithm base 2 of @math{|x|}, rounded
|
||||
down to an integer.
|
||||
precisely, if @var{x} is finite and nonzero, the value is the
|
||||
logarithm base 2 of @math{|x|}, rounded down to an integer.
|
||||
If @var{x} is zero, infinite, or a NaN, the value is minus infinity,
|
||||
plus infinity, or a NaN respectively.
|
||||
|
||||
@example
|
||||
(logb 10)
|
||||
@result{} 3
|
||||
(logb 10.0e20)
|
||||
@result{} 69
|
||||
(logb 0)
|
||||
@result{} -1.0e+INF
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
|
|
4
etc/NEWS
4
etc/NEWS
|
@ -1112,6 +1112,10 @@ old-style backquotes as new-style, bind the new variable
|
|||
integer, Emacs now signals an error if the number is too large for the
|
||||
implementation to format.
|
||||
|
||||
** logb now returns infinity when given an infinite or zero argument,
|
||||
and returns a NaN when given a NaN. Formerly, it returned an extreme
|
||||
fixnum for such arguments.
|
||||
|
||||
---
|
||||
** Some functions and variables obsolete since Emacs 22 have been removed:
|
||||
archive-mouse-extract, assoc-ignore-case, assoc-ignore-representation,
|
||||
|
|
|
@ -306,27 +306,22 @@ This is the same as the exponent of a float. */)
|
|||
if (FLOATP (arg))
|
||||
{
|
||||
double f = XFLOAT_DATA (arg);
|
||||
|
||||
if (f == 0)
|
||||
value = MOST_NEGATIVE_FIXNUM;
|
||||
else if (isfinite (f))
|
||||
{
|
||||
int ivalue;
|
||||
frexp (f, &ivalue);
|
||||
value = ivalue - 1;
|
||||
}
|
||||
else
|
||||
value = MOST_POSITIVE_FIXNUM;
|
||||
return make_float (-HUGE_VAL);
|
||||
if (!isfinite (f))
|
||||
return f < 0 ? make_float (-f) : arg;
|
||||
int ivalue;
|
||||
frexp (f, &ivalue);
|
||||
value = ivalue - 1;
|
||||
}
|
||||
else if (BIGNUMP (arg))
|
||||
else if (!FIXNUMP (arg))
|
||||
value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1;
|
||||
else
|
||||
{
|
||||
eassert (FIXNUMP (arg));
|
||||
EMACS_INT i = eabs (XFIXNUM (arg));
|
||||
value = (i == 0
|
||||
? MOST_NEGATIVE_FIXNUM
|
||||
: EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (i));
|
||||
EMACS_INT i = XFIXNUM (arg);
|
||||
if (i == 0)
|
||||
return make_float (-HUGE_VAL);
|
||||
value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i));
|
||||
}
|
||||
|
||||
return make_fixnum (value);
|
||||
|
|
Loading…
Add table
Reference in a new issue