summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--lib/libm/math.c2
-rw-r--r--lib/libm/sf_frexp.c70
-rw-r--r--lib/libm/sf_modf.c82
-rw-r--r--stmhal/Makefile2
-rw-r--r--tests/float/math_fun.py11
5 files changed, 164 insertions, 3 deletions
diff --git a/lib/libm/math.c b/lib/libm/math.c
index 0998de227a..d5b6164a49 100644
--- a/lib/libm/math.c
+++ b/lib/libm/math.c
@@ -122,8 +122,6 @@ float tgammaf(float x) { return 0.0; }
float lgammaf(float x) { return 0.0; }
float erff(float x) { return 0.0; }
float erfcf(float x) { return 0.0; }
-float modff(float x, float *y) { return 0.0; }
-float frexpf(float x, int *exp) { return 0.0; }
float ldexpf(float x, int exp) { return 0.0; }
/*****************************************************************************/
diff --git a/lib/libm/sf_frexp.c b/lib/libm/sf_frexp.c
new file mode 100644
index 0000000000..397373fdeb
--- /dev/null
+++ b/lib/libm/sf_frexp.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * These math functions are taken from newlib-nano-2, the newlib/libm/math
+ * directory, available from https://github.com/32bitmicro/newlib-nano-2.
+ *
+ * Appropriate copyright headers are reproduced below.
+ */
+
+/* sf_frexp.c -- float version of s_frexp.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.3554432000e+07; /* 0x4c000000 */
+
+#ifdef __STDC__
+ float frexpf(float x, int *eptr)
+#else
+ float frexpf(x, eptr)
+ float x; int *eptr;
+#endif
+{
+ __int32_t hx, ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(!FLT_UWORD_IS_FINITE(ix)||FLT_UWORD_IS_ZERO(ix)) return x; /* 0,inf,nan */
+ if (FLT_UWORD_IS_SUBNORMAL(ix)) { /* subnormal */
+ x *= two25;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -25;
+ }
+ *eptr += (ix>>23)-126;
+ hx = (hx&0x807fffff)|0x3f000000;
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+
+#ifdef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double frexp(double x, int *eptr)
+#else
+ double frexp(x, eptr)
+ double x; int *eptr;
+#endif
+{
+ return (double) frexpf((float) x, eptr);
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/lib/libm/sf_modf.c b/lib/libm/sf_modf.c
new file mode 100644
index 0000000000..4fcae057a5
--- /dev/null
+++ b/lib/libm/sf_modf.c
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * These math functions are taken from newlib-nano-2, the newlib/libm/common
+ * directory, available from https://github.com/32bitmicro/newlib-nano-2.
+ *
+ * Appropriate copyright headers are reproduced below.
+ */
+
+/* sf_modf.c -- float version of s_modf.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const float one = 1.0;
+#else
+static float one = 1.0;
+#endif
+
+#ifdef __STDC__
+ float modff(float x, float *iptr)
+#else
+ float modff(x, iptr)
+ float x,*iptr;
+#endif
+{
+ __int32_t i0,j0;
+ __uint32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
+ if(j0<23) { /* integer part in x */
+ if(j0<0) { /* |x|<1 */
+ SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) { /* x is integral */
+ __uint32_t ix;
+ *iptr = x;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
+ return x;
+ } else {
+ SET_FLOAT_WORD(*iptr,i0&(~i));
+ return x - *iptr;
+ }
+ }
+ } else { /* no fraction part */
+ __uint32_t ix;
+ *iptr = x*one;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
+ return x;
+ }
+}
+
+#ifdef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double modf(double x, double *iptr)
+#else
+ double modf(x, iptr)
+ double x,*iptr;
+#endif
+{
+ return (double) modff((float) x, (float *) iptr);
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/stmhal/Makefile b/stmhal/Makefile
index aaae4ba106..9fa7b2acfb 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -81,6 +81,8 @@ SRC_LIB = $(addprefix lib/,\
libm/sf_sin.c \
libm/sf_cos.c \
libm/sf_tan.c \
+ libm/sf_frexp.c \
+ libm/sf_modf.c \
fatfs/ff.c \
fatfs/option/ccsbcs.c \
mp-readline/readline.c \
diff --git a/tests/float/math_fun.py b/tests/float/math_fun.py
index 7e5001ad03..03ee8e85d2 100644
--- a/tests/float/math_fun.py
+++ b/tests/float/math_fun.py
@@ -33,7 +33,6 @@ functions = [('sqrt', sqrt, p_test_values),
('ceil', ceil, test_values),
('fabs', fabs, test_values),
('floor', floor, test_values),
- #('frexp', frexp, test_values),
('trunc', trunc, test_values)
]
@@ -42,6 +41,16 @@ for function_name, function, test_vals in functions:
for value in test_vals:
print("{:.5g}".format(function(value)))
+tuple_functions = [('frexp', frexp, test_values),
+ ('modf', modf, test_values),
+ ]
+
+for function_name, function, test_vals in tuple_functions:
+ print(function_name)
+ for value in test_vals:
+ x, y = function(value)
+ print("{:.5g} {:.5g}".format(x, y))
+
binary_functions = [('copysign', copysign, [(23., 42.), (-23., 42.), (23., -42.),
(-23., -42.), (1., 0.0), (1., -0.0)])
]