diff options
author | das <das@FreeBSD.org> | 2007-12-17 03:53:38 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2007-12-17 03:53:38 +0000 |
commit | d717f8cf061b8e1ae723ff0b21dbf7a39e76252a (patch) | |
tree | 99f2f45aa85cda099081bdd655d43fdb2ef0e56f /lib/msun/src | |
parent | 42e5c27a872aa4dc472aa23e125eba748db17c52 (diff) | |
download | FreeBSD-src-d717f8cf061b8e1ae723ff0b21dbf7a39e76252a.zip FreeBSD-src-d717f8cf061b8e1ae723ff0b21dbf7a39e76252a.tar.gz |
Add logbl(3) to libm.
Diffstat (limited to 'lib/msun/src')
-rw-r--r-- | lib/msun/src/s_logb.c | 6 | ||||
-rw-r--r-- | lib/msun/src/s_logbl.c | 55 |
2 files changed, 61 insertions, 0 deletions
diff --git a/lib/msun/src/s_logb.c b/lib/msun/src/s_logb.c index f667bf2..4091429 100644 --- a/lib/msun/src/s_logb.c +++ b/lib/msun/src/s_logb.c @@ -20,6 +20,8 @@ static char rcsid[] = "$FreeBSD$"; * Use ilogb instead. */ +#include <float.h> + #include "math.h" #include "math_private.h" @@ -42,3 +44,7 @@ logb(double x) } else return (double) ((ix>>20)-1023); } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(logb, logbl); +#endif diff --git a/lib/msun/src/s_logbl.c b/lib/msun/src/s_logbl.c new file mode 100644 index 0000000..7e88e36 --- /dev/null +++ b/lib/msun/src/s_logbl.c @@ -0,0 +1,55 @@ +/* + * From: @(#)s_ilogb.c 5.1 93/09/24 + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifndef lint +static char rcsid[] = "$FreeBSD$"; +#endif + +#include <float.h> +#include <limits.h> +#include <math.h> + +#include "fpmath.h" + +long double +logbl(long double x) +{ + union IEEEl2bits u; + unsigned long m; + int b; + + u.e = x; + if (u.bits.exp == 0) { + if ((u.bits.manl | u.bits.manh) == 0) { /* x == 0 */ + u.bits.sign = 1; + return (1.0L / u.e); + } + /* denormalized */ + if (u.bits.manh == 0) { + m = 1lu << (LDBL_MANL_SIZE - 1); + for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1) + b++; + } else { + m = 1lu << (LDBL_MANH_SIZE - 1); + for (b = 0; !(u.bits.manh & m); m >>= 1) + b++; + } +#ifdef LDBL_IMPLICIT_NBIT + b++; +#endif + return ((long double)(LDBL_MIN_EXP - b - 1)); + } + if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) /* normal */ + return ((long double)(u.bits.exp - LDBL_MAX_EXP + 1)); + else /* +/- inf or nan */ + return (x * x); +} |