summaryrefslogtreecommitdiff
path: root/lib/libc/gen
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2005-02-01 15:12:31 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2005-02-01 15:12:31 +0000
commit1b0c2756f2ed59c98af0244f8e4bc953aa86d9d5 (patch)
tree5f0e1cf4c46cc06d7847c4dc9c5161018e757400 /lib/libc/gen
parent7f1209ff29fd072e2f8d1f49392e63d47962736b (diff)
Replace broken frexp() with a working one from FreeBSD. There's
no need to have a copy for each platform with ieee floating point, only vax needs a special version (which probably has similar bugs). OK and with help from otto@
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/Makefile.inc4
-rw-r--r--lib/libc/gen/frexp.c70
2 files changed, 72 insertions, 2 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 7e37e95c210..91c6a6e4468 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.36 2004/02/01 17:53:59 deraadt Exp $
+# $OpenBSD: Makefile.inc,v 1.37 2005/02/01 15:12:28 millert Exp $
# gen sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gen ${LIBCSRCDIR}/gen
@@ -6,7 +6,7 @@
SRCS+= alarm.c assert.c auth_subr.c authenticate.c \
basename.c clock.c closedir.c confstr.c ctermid.c ctype_.c \
daemon.c devname.c dirname.c disklabel.c elf_hash.c err.c \
- errx.c errlist.c errno.c exec.c fnmatch.c fstab.c ftok.c \
+ errx.c errlist.c errno.c exec.c fnmatch.c frexp.c fstab.c ftok.c \
fts.c ftw.c getbsize.c getcap.c getcwd.c getdomainname.c \
getgrent.c getgrouplist.c gethostname.c getloadavg.c \
getlogin.c getmntinfo.c getnetgrent.c getpagesize.c getpwent.c \
diff --git a/lib/libc/gen/frexp.c b/lib/libc/gen/frexp.c
new file mode 100644
index 00000000000..95c73a32d07
--- /dev/null
+++ b/lib/libc/gen/frexp.c
@@ -0,0 +1,70 @@
+/* $OpenBSD: frexp.c,v 1.1 2005/02/01 15:12:28 millert Exp $ */
+
+/*-
+ * Copyright (c) 2004 David Schultz <das@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: frexp.c,v 1.1 2004/07/18 21:23:39 das Exp $
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: frexp.c,v 1.1 2005/02/01 15:12:28 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <machine/ieee.h>
+#include <math.h>
+
+double
+frexp(double v, int *ex)
+{
+ union {
+ double v;
+ struct ieee_double s;
+ } u;
+
+ u.v = v;
+ switch (u.s.dbl_exp) {
+ case 0: /* 0 or subnormal */
+ if ((u.s.dbl_fracl | u.s.dbl_frach) == 0) {
+ *ex = 0;
+ } else {
+ /*
+ * The power of 2 is arbitrary, any value from 54 to
+ * 1024 will do.
+ */
+ u.v *= 0x1.0p514;
+ *ex = u.s.dbl_exp - (DBL_EXP_BIAS - 1 + 514);
+ u.s.dbl_exp = DBL_EXP_BIAS - 1;
+ }
+ break;
+ case DBL_EXP_INFNAN: /* Inf or NaN; value of *ex is unspecified */
+ break;
+ default: /* normal */
+ *ex = u.s.dbl_exp - (DBL_EXP_BIAS - 1);
+ u.s.dbl_exp = DBL_EXP_BIAS - 1;
+ break;
+ }
+ return (u.v);
+}