shithub: npe

Download patch

ref: e4cdde6bf5fd9562d826cc2f5a30e3774c247432
parent: 1cf523a5e0dc72fd9d41aa434e3359ff08c5406e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Aug 17 14:16:14 EDT 2023

npe: add cbrtf

--- a/include/npe/math.h
+++ b/include/npe/math.h
@@ -59,5 +59,6 @@
 double fmax(double x, double y);
 float ldexpf(float x, int n);
 float hypotf(float x, float y);
+float cbrtf(float x);
 
 #endif
--- /dev/null
+++ b/libnpe/cbrtf.c
@@ -1,0 +1,67 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+/* cbrtf(x)
+ * Return cube root of x
+ */
+
+#include <u.h>
+#include <libc.h>
+
+static const unsigned
+B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
+
+float
+cbrtf(float x)
+{
+	double r,T;
+	union {float f; u32int i;} u = {x};
+	u32int hx = u.i & 0x7fffffff;
+
+	if (hx >= 0x7f800000)  /* cbrt(NaN,INF) is itself */
+		return x + x;
+
+	/* rough cbrt to 5 bits */
+	if (hx < 0x00800000) {  /* zero or subnormal? */
+		if (hx == 0)
+			return x;  /* cbrt(+-0) is itself */
+		u.f = x*16777210.0f;//0x1p24f;
+		hx = u.i & 0x7fffffff;
+		hx = hx/3 + B2;
+	} else
+		hx = hx/3 + B1;
+	u.i &= 0x80000000;
+	u.i |= hx;
+
+	/*
+	 * First step Newton iteration (solving t*t-x/t == 0) to 16 bits.  In
+	 * double precision so that its terms can be arranged for efficiency
+	 * without causing overflow or underflow.
+	 */
+	T = u.f;
+	r = T*T*T;
+	T = T*((double)x+x+r)/(x+r+r);
+
+	/*
+	 * Second step Newton iteration to 47 bits.  In double precision for
+	 * efficiency and accuracy.
+	 */
+	r = T*T*T;
+	T = T*((double)x+x+r)/(x+r+r);
+
+	/* rounding to 24 bits is perfect in round-to-nearest mode */
+	return T;
+}
--- a/libnpe/mkfile
+++ b/libnpe/mkfile
@@ -13,6 +13,7 @@
 	_npe.$O\
 	acosh.$O\
 	basename.$O\
+	cbrtf.$O\
 	closedir.$O\
 	dirfd.$O\
 	dirname.$O\