summaryrefslogtreecommitdiffstats
path: root/lib/libm/src
diff options
context:
space:
mode:
authorbrad <brad@openbsd.org>2006-03-18 20:13:24 +0000
committerbrad <brad@openbsd.org>2006-03-18 20:13:24 +0000
commit55dfb921038f3a9013736ac2082905437b98a6fa (patch)
treed4cbaf972eaad0273b8df1de8e0aaae661cfc47c /lib/libm/src
parentfix problems found by Coverity via NetBSD: (diff)
downloadwireguard-openbsd-55dfb921038f3a9013736ac2082905437b98a6fa.tar.xz
wireguard-openbsd-55dfb921038f3a9013736ac2082905437b98a6fa.zip
add some more C99 functions: trunc(3) and truncf(3).
From FreeBSD ok deraadt@ millert@ otto@ jmc@
Diffstat (limited to 'lib/libm/src')
-rw-r--r--lib/libm/src/s_trunc.c63
-rw-r--r--lib/libm/src/s_truncf.c55
2 files changed, 118 insertions, 0 deletions
diff --git a/lib/libm/src/s_trunc.c b/lib/libm/src/s_trunc.c
new file mode 100644
index 00000000000..93416511851
--- /dev/null
+++ b/lib/libm/src/s_trunc.c
@@ -0,0 +1,63 @@
+/* @(#)s_floor.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.
+ * ====================================================
+ */
+
+#if 0
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/msun/src/s_trunc.c,v 1.1 2004/06/20 09:25:43 das Exp $");
+#endif
+
+/*
+ * trunc(x)
+ * Return x rounded toward 0 to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to trunc(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const double huge = 1.0e300;
+
+double
+trunc(double x)
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */
+ i0 &= 0x80000000U;
+ i1 = 0;
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) /* raise inexact flag */
+ i1 &= (~i);
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
diff --git a/lib/libm/src/s_truncf.c b/lib/libm/src/s_truncf.c
new file mode 100644
index 00000000000..5480dddac9e
--- /dev/null
+++ b/lib/libm/src/s_truncf.c
@@ -0,0 +1,55 @@
+/* @(#)s_floor.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.
+ * ====================================================
+ */
+
+#if 0
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/msun/src/s_truncf.c,v 1.1 2004/06/20 09:25:43 das Exp $");
+#endif
+
+/*
+ * truncf(x)
+ * Return x rounded toward 0 to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to truncf(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const float huge = 1.0e30F;
+
+float
+truncf(float x)
+{
+ int32_t i0,j0;
+ u_int32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0F) /* |x|<1, so return 0*sign(x) */
+ i0 &= 0x80000000;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ if(huge+x>0.0F) /* raise inexact flag */
+ i0 &= (~i);
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ return x;
+}