summaryrefslogtreecommitdiffstats
path: root/lib/libm/src/s_nexttowardf.c
diff options
context:
space:
mode:
authormartynas <martynas@openbsd.org>2011-07-06 00:02:42 +0000
committermartynas <martynas@openbsd.org>2011-07-06 00:02:42 +0000
commit49393c004c040ee201e6408db68882c3fe4cb110 (patch)
treef3298ab7f1009e5bcf7f59709937ab1bf7c9db6e /lib/libm/src/s_nexttowardf.c
parenta short note about PR_DEBUGCHK (diff)
downloadwireguard-openbsd-49393c004c040ee201e6408db68882c3fe4cb110.tar.xz
wireguard-openbsd-49393c004c040ee201e6408db68882c3fe4cb110.zip
Finalize work on the math library. It's time to do this monster
commit, and deal with problems (if any) in tree. Note that this adds the following functions. Ports with hacks might need adjustments. nexttoward(3), fma(3), nexttowardf(3), fmaf(3), acoshl(3), asinhl(3), atanhl(3), coshl(3), sinhl(3), tanhl(3), expl(3), expm1l(3), logl(3), log10l(3), log1pl(3), log2l(3), modfl(3), cbrtl(3), hypotl(3), powl(3), erfl(3), erfcl(3), lgammal(3), tgammal(3), ceill(3), floorl(3), lrintl(3), llrintl(3), roundl(3), lroundl(3), llroundl(3), truncl(3), fmodl(3), remainderl(3), remquol(3), nextafterl(3), nexttowardl(3), fmal(3). With this commit, our library implements all functionality required by C99. Documentation bits will follow.
Diffstat (limited to 'lib/libm/src/s_nexttowardf.c')
-rw-r--r--lib/libm/src/s_nexttowardf.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/libm/src/s_nexttowardf.c b/lib/libm/src/s_nexttowardf.c
new file mode 100644
index 00000000000..ee22018343d
--- /dev/null
+++ b/lib/libm/src/s_nexttowardf.c
@@ -0,0 +1,74 @@
+/* @(#)s_nextafter.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.
+ * ====================================================
+ */
+
+/* IEEE functions
+ * nexttowardf(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * This is for machines which use the same binary type for double and
+ * long double.
+ * Special cases:
+ */
+
+#include <math.h>
+#include <float.h>
+
+#include "math_private.h"
+
+float
+nexttowardf(float x, long double y)
+{
+ int32_t hx,hy,ix,iy;
+ u_int32_t ly;
+
+ GET_FLOAT_WORD(hx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ volatile float u;
+ SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
+ u = x;
+ u = u * u; /* raise underflow flag */
+ return x;
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hy<0||(ix>>23)>(iy>>20)-0x380
+ || ((ix>>23)==(iy>>20)-0x380
+ && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x > y, x -= ulp */
+ hx -= 1;
+ else /* x < y, x += ulp */
+ hx += 1;
+ } else { /* x < 0 */
+ if(hy>=0||(ix>>23)>(iy>>20)-0x380
+ || ((ix>>23)==(iy>>20)-0x380
+ && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x < y, x -= ulp */
+ hx -= 1;
+ else /* x > y, x += ulp */
+ hx += 1;
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ return x;
+ }
+ if(hy<0x00800000) {
+ volatile float u = x*x; /* underflow */
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}