diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
commit | 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc (patch) | |
tree | 68c3dbf3f2c6fd5d49777def9914d77b5cd4589d /newlib/libm/test/math2.c | |
parent | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (diff) | |
download | cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.gz cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.bz2 cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.zip |
import newlib-2000-02-17 snapshot
Diffstat (limited to 'newlib/libm/test/math2.c')
-rw-r--r-- | newlib/libm/test/math2.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/newlib/libm/test/math2.c b/newlib/libm/test/math2.c new file mode 100644 index 000000000..50b537646 --- /dev/null +++ b/newlib/libm/test/math2.c @@ -0,0 +1,232 @@ + +#include "test.h" +#include <errno.h> + + +int +_DEFUN_VOID(randi) +{ + static int next; + next = (next * 1103515245) + 12345; + return ((next >> 16) & 0xffff); +} + +double _DEFUN_VOID(randx) +{ + double res; + + do + { + union { + short parts[4]; + double res; + } u; + + u.parts[0] = randi(); + u.parts[1] = randi(); + u.parts[2] = randi(); + u.parts[3] = randi(); + res = u.res; + + } while (!finite(res)); + + return res ; +} + +/* Return a random double, but bias for numbers closer to 0 */ +double _DEFUN_VOID(randy) +{ + int pow; + double r= randx(); + r = frexp(r, &pow); + return ldexp(r, randi() & 0x1f); +} + +void +_DEFUN_VOID(test_frexp) +{ + int i; + double r; + int t; + + float xf; + double gives; + + int pow; + + + /* Frexp of x return a and n, where a * 2**n == x, so test this with a + set of random numbers */ + for (t = 0; t < 2; t++) + { + for (i = 0; i < 1000; i++) + { + + double x = randx(); + line(i); + switch (t) + { + case 0: + newfunc("frexp/ldexp"); + r = frexp(x, &pow); + if (r > 1.0 || r < -1.0) + { + /* Answer can never be > 1 or < 1 */ + test_iok(0,1); + } + + gives = ldexp(r ,pow); + test_mok(gives,x,62); + break; + case 1: + newfunc("frexpf/ldexpf"); + if (x > FLT_MIN && x < FLT_MAX) + { + /* test floats too, but they have a smaller range so make sure x + isn't too big. Also x can get smaller than a float can + represent to make sure that doesn't happen too */ + xf = x; + r = frexpf(xf, &pow); + if (r > 1.0 || r < -1.0) + { + /* Answer can never be > 1 or < -1 */ + test_iok(0,1); + } + + gives = ldexpf(r ,pow); + test_mok(gives,x, 32); + + } + } + + } + + } + + /* test a few numbers manually to make sure frexp/ldexp are not + testing as ok because both are broken */ + + r = frexp(64.0, &i); + + test_mok(r, 0.5,64); + test_iok(i, 7); + + r = frexp(96.0, &i); + + test_mok(r, 0.75, 64); + test_iok(i, 7); + +} + +/* Test mod - this is given a real hammering by the strtod type + routines, here are some more tests. + + By definition + + modf = func(value, &iptr) + + (*iptr + modf) == value + + we test this + +*/ +void +_DEFUN_VOID(test_mod) +{ + int i; + + newfunc("modf"); + + + for (i = 0; i < 1000; i++) + { + double intpart; + double n; + line(i); + n = randx(); + if (finite(n) && n != 0.0 ) + { + double r = modf(n, &intpart); + line(i); + test_mok(intpart + r, n, 63); + } + + } + newfunc("modff"); + + for (i = 0; i < 1000; i++) + { + float intpart; + double nd; + line(i); + nd = randx() ; + if (nd < FLT_MAX && finitef(nd) && nd != 0.0) + { + float n = nd; + double r = modff(n, &intpart); + line(i); + test_mok(intpart + r, n, 32); + } + } + + +} + +/* +Test pow by multiplying logs +*/ +void +_DEFUN_VOID(test_pow) +{ + unsigned int i; + newfunc("pow"); + + for (i = 0; i < 1000; i++) + { + double n1; + double n2; + double res; + double shouldbe; + + line(i); + n1 = fabs(randy()); + n2 = fabs(randy()/100.0); + res = pow(n1, n2); + shouldbe = exp(log(n1) * n2); + test_mok(shouldbe, res,64); + } + + newfunc("powf"); + + for (i = 0; i < 1000; i++) + { + double n1; + double n2; + double res; + double shouldbe; + + errno = 0; + + line(i); + n1 = fabs(randy()); + n2 = fabs(randy()/100.0); + res = powf(n1, n2); + shouldbe = expf(logf(n1) * n2); + if (!errno) + test_mok(shouldbe, res,28); + } + + + + +} + + + +void +_DEFUN_VOID(test_math2) +{ + test_mod(); + test_frexp(); + test_pow(); +} |