diff options
author | 2008-12-09 20:00:35 +0000 | |
---|---|---|
committer | 2008-12-09 20:00:35 +0000 | |
commit | 390c8400525fc0ecc9e2c49c2246076b1b49fe19 (patch) | |
tree | 53eacecd5d140dfe4af32e85cbd374f340c935fc /lib/libm/src/s_logbl.c | |
parent | - add long double signbit (diff) | |
download | wireguard-openbsd-390c8400525fc0ecc9e2c49c2246076b1b49fe19.tar.xz wireguard-openbsd-390c8400525fc0ecc9e2c49c2246076b1b49fe19.zip |
- 80-bit and quad precision trigonometric and other most
important functions: acosl, asinl, atanl, atan2l, cosl,
sinl, tanl, exp2l, frexpl, ilogbl, ldexpl, logbl, scalbnl,
fabsl, hypotl, powl, sqrtl, rintl, copysignl, nanl, fdiml,
fmaxl, fminl. mostly taken from freebsd, needed alot of
changes to adapt. note, these are all c versions; and are
quite slow when architectures have, e.g. sqrt. assembly
versions will be added afterwards
- make them .weak/__weak_alias to the double precision
versions on other archs
- no need to have two finites. finite() and finitef() are
non-standard 3BSD obsolete versions of isfinite. remove
from libm. make them weak_alias in libc to __isfinite and
__isfinitef instead. similarly make 3BSD obsolete versions
of isinf, isinff, isnan, isnanf weak_aliases to C99's
__isinf, __isinff, __isnan, __isnanf
- remove unused infinity.c. the c library has infinities
for each supported platform
- use STRICT_ASSIGN cast hack for _kernel_rem_pio2, so that
the double version has a chance of working on i386 with
extra precision
- avoid storing multiple copies of the pi/2 array, since
it won't vary
- bump major due to removed finite/finitef. although they
will be in libc, which anything is linked to, minor bump
might be enough
ok millert@. tested by sthen@, jsg@, ajacoutot@, kili@, naddy@
Diffstat (limited to 'lib/libm/src/s_logbl.c')
-rw-r--r-- | lib/libm/src/s_logbl.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/libm/src/s_logbl.c b/lib/libm/src/s_logbl.c new file mode 100644 index 00000000000..7de6ede4fd0 --- /dev/null +++ b/lib/libm/src/s_logbl.c @@ -0,0 +1,77 @@ +/* $OpenBSD: s_logbl.c,v 1.1 2008/12/09 20:00:35 martynas Exp $ */ +/* + * 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. + * ==================================================== + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <float.h> +#include <limits.h> +#include <math.h> + +long double +logbl(long double x) +{ + union { + long double e; + struct ieee_ext bits; + } u; + unsigned long m; + int b; + + u.e = x; + if (u.bits.ext_exp == 0) { + if ((u.bits.ext_fracl +#ifdef EXT_FRACLMBITS + | u.bits.ext_fraclm +#endif /* EXT_FRACLMBITS */ +#ifdef EXT_FRACHMBITS + | u.bits.ext_frachm +#endif /* EXT_FRACHMBITS */ + | u.bits.ext_frach) == 0) { /* x == 0 */ + u.bits.ext_sign = 1; + return (1.0L / u.e); + } + /* denormalized */ + if (u.bits.ext_frach == 0 +#ifdef EXT_FRACHMBITS + && u.bits.ext_frachm == 0 +#endif + ) { + m = 1lu << (EXT_FRACLBITS - 1); + for (b = EXT_FRACHBITS; !(u.bits.ext_fracl & m); m >>= 1) + b++; +#if defined(EXT_FRACHMBITS) && defined(EXT_FRACLMBITS) + m = 1lu << (EXT_FRACLMBITS - 1); + for (b += EXT_FRACHMBITS; !(u.bits.ext_fraclm & m); + m >>= 1) + b++; +#endif /* defined(EXT_FRACHMBITS) && defined(EXT_FRACLMBITS) */ + } else { + m = 1lu << (EXT_FRACHBITS - 1); + for (b = 0; !(u.bits.ext_frach & m); m >>= 1) + b++; +#ifdef EXT_FRACHMBITS + m = 1lu << (EXT_FRACHMBITS - 1); + for (; !(u.bits.ext_frachm & m); m >>= 1) + b++; +#endif /* EXT_FRACHMBITS */ + } +#ifdef EXT_IMPLICIT_NBIT + b++; +#endif + return ((long double)(LDBL_MIN_EXP - b - 1)); + } + if (u.bits.ext_exp < (LDBL_MAX_EXP << 1) - 1) /* normal */ + return ((long double)(u.bits.ext_exp - LDBL_MAX_EXP + 1)); + else /* +/- inf or nan */ + return (x * x); +} |