diff options
author | das <das@FreeBSD.org> | 2004-07-19 08:16:10 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2004-07-19 08:16:10 +0000 |
commit | 7aef999db62cfb1370a29fad2bbee5c489b660ec (patch) | |
tree | 0682171fd2934d939f73a83ae70efdcd286af303 /lib/msun/src | |
parent | 67d8cb396ecf47239ba3bff7d7a8f44ed7ceb7d5 (diff) | |
download | FreeBSD-src-7aef999db62cfb1370a29fad2bbee5c489b660ec.zip FreeBSD-src-7aef999db62cfb1370a29fad2bbee5c489b660ec.tar.gz |
Fix two bugs in the signbit() macro, which was implemented last year:
- It was added to libc instead of libm. Hopefully no programs rely
on this mistake.
- It didn't work properly on large long doubles because its argument
was converted to type double, resulting in undefined behavior.
Diffstat (limited to 'lib/msun/src')
-rw-r--r-- | lib/msun/src/math.h | 7 | ||||
-rw-r--r-- | lib/msun/src/s_signbit.c | 58 |
2 files changed, 64 insertions, 1 deletions
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h index 76598e3..b85ef96 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -113,7 +113,10 @@ extern const union __nan_un { #define isunordered(x, y) (isnan(x) || isnan(y)) #endif /* __MATH_BUILTIN_RELOPS */ -#define signbit(x) __signbit(x) +#define signbit(x) \ + ((sizeof (x) == sizeof (float)) ? __signbitf(x) \ + : (sizeof (x) == sizeof (double)) ? __signbit(x) \ + : __signbitl(x)) typedef __double_t double_t; typedef __float_t float_t; @@ -215,6 +218,8 @@ int __isnormalf(float) __pure2; int __isnormal(double) __pure2; int __isnormall(long double) __pure2; int __signbit(double) __pure2; +int __signbitf(float) __pure2; +int __signbitl(long double) __pure2; double acos(double); double asin(double); diff --git a/lib/msun/src/s_signbit.c b/lib/msun/src/s_signbit.c new file mode 100644 index 0000000..01eb3ab --- /dev/null +++ b/lib/msun/src/s_signbit.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <math.h> + +#include "fpmath.h" + +int +__signbit(double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.sign); +} + +int +__signbitf(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.sign); +} + +int +__signbitl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + return (u.bits.sign); +} |