summaryrefslogtreecommitdiff
path: root/newlib/libm/test/math.c
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2000-02-17 19:39:46 +0000
committerChristopher Faylor <cgf@redhat.com>2000-02-17 19:39:46 +0000
commit6d491d8ad9122891d1a48447e8c49702eb678921 (patch)
tree45619a131b9f211ceca9fce7a866328344bf00ec /newlib/libm/test/math.c
parentbd592806f45307757c24ec3f75bdefe13abfd51f (diff)
downloadgdb-6d491d8ad9122891d1a48447e8c49702eb678921.tar.gz
import newlib-2000-02-17 snapshotcvs/SNAPSHOT
Diffstat (limited to 'newlib/libm/test/math.c')
-rw-r--r--newlib/libm/test/math.c472
1 files changed, 472 insertions, 0 deletions
diff --git a/newlib/libm/test/math.c b/newlib/libm/test/math.c
new file mode 100644
index 00000000000..df63c2df25f
--- /dev/null
+++ b/newlib/libm/test/math.c
@@ -0,0 +1,472 @@
+/*
+ Test the library maths functions using trusted precomputed test
+ vectors.
+
+ These vectors were originally generated on a sun3 with a 68881 using
+ 80 bit precision, but ...
+
+ Each function is called with a variety of interesting arguments.
+ Note that many of the polynomials we use behave badly when the
+ domain is stressed, so the numbers in the vectors depend on what is
+ useful to test - eg sin(1e30) is pointless - the arg has to be
+ reduced modulo pi, and after that there's no bits of significance
+ left to evaluate with - any number would be just as precise as any
+ other.
+
+
+*/
+
+#include "test.h"
+#include <math.h>
+#include <ieeefp.h>
+#include <float.h>
+#include <math.h>
+#include <errno.h>
+#include <stdio.h>
+
+int inacc;
+
+int merror;
+double mretval = 64;
+int traperror = 1;
+char *mname;
+
+int verbose;
+
+/* To test exceptions - we trap them all and return a known value */
+int
+_DEFUN(matherr,(e),
+ struct exception *e)
+{
+ if (traperror)
+ {
+ merror = e->type + 12;
+ mname = e->name;
+ e->retval = mretval;
+ errno = merror + 24;
+ return 1;
+ }
+ return 0;
+}
+
+
+void _DEFUN(translate_to,(file,r),
+ FILE *file _AND
+ double r)
+{
+ __ieee_double_shape_type bits;
+ bits.value = r;
+ fprintf(file, "0x%08x, 0x%08x", bits.parts.msw, bits.parts.lsw);
+}
+
+int
+_DEFUN(ffcheck,( is, p, name, serrno, merror),
+ double is _AND
+ one_line_type *p _AND
+ char *name _AND
+ int serrno _AND
+ int merror)
+{
+ /* Make sure the answer isn't to far wrong from the correct value */
+ __ieee_double_shape_type correct, isbits;
+ int mag;
+ isbits.value = is;
+
+ correct.parts.msw = p->qs[0].msw;
+ correct.parts.lsw = p->qs[0].lsw;
+
+ mag = mag_of_error(correct.value, is);
+
+ if (mag < p->error_bit)
+ {
+ inacc ++;
+
+ printf("%s:%d, inaccurate answer: bit %d (%08x%08x %08x%08x) (%g %g)\n",
+ name, p->line, mag,
+ correct.parts.msw,
+ correct.parts.lsw,
+ isbits.parts.msw,
+ isbits.parts.lsw,
+ correct.value, is);
+ }
+
+#if 0
+ if (p->qs[0].merror != merror)
+ {
+ printf("testing %s_vec.c:%d, matherr wrong: %d %d\n",
+ name, p->line, merror, p->qs[0].merror);
+ }
+
+ if (p->qs[0].errno_val != errno)
+ {
+ printf("testing %s_vec.c:%d, errno wrong: %d %d\n",
+ name, p->line, errno, p->qs[0].errno_val);
+
+ }
+#endif
+ return mag;
+}
+
+double
+_DEFUN(thedouble, (msw, lsw),
+ long msw _AND
+ long lsw)
+{
+ __ieee_double_shape_type x;
+
+ x.parts.msw = msw;
+ x.parts.lsw = lsw;
+ return x.value;
+}
+
+int calc;
+int reduce;
+
+
+_DEFUN(frontline,(f, mag, p, result, merror, errno, args, name),
+ FILE *f _AND
+ int mag _AND
+ one_line_type *p _AND
+ double result _AND
+ int merror _AND
+ int errno _AND
+ char *args _AND
+ char *name)
+{
+ if (reduce && p->error_bit < mag)
+ {
+ fprintf(f, "{%2d,", p->error_bit);
+ }
+ else
+ {
+ fprintf(f, "{%2d,",mag);
+ }
+
+
+ fprintf(f,"%2d,%3d,", merror,errno);
+ fprintf(f, "__LINE__, ");
+
+ if (calc)
+ {
+ translate_to(f, result);
+ }
+ else
+ {
+ translate_to(f, thedouble(p->qs[0].msw, p->qs[0].lsw));
+ }
+
+ fprintf(f, ", ");
+
+ fprintf(f,"0x%08x, 0x%08x", p->qs[1].msw, p->qs[1].lsw);
+
+
+ if (args[2])
+ {
+ fprintf(f, ", ");
+ fprintf(f,"0x%08x, 0x%08x", p->qs[2].msw, p->qs[2].lsw);
+ }
+
+ fprintf(f,"}, /* %g=f(%g",result,
+ thedouble(p->qs[1].msw, p->qs[1].lsw));
+
+ if (args[2])
+ {
+ fprintf(f,", %g", thedouble(p->qs[2].msw,p->qs[2].lsw));
+ }
+ fprintf(f, ")*/\n");
+}
+
+_DEFUN(finish,(f, vector, result , p, args, name),
+ FILE *f _AND
+ int vector _AND
+ double result _AND
+ one_line_type *p _AND
+ char *args _AND
+ char *name)
+{
+ int mag;
+
+ mag = ffcheck(result, p,name, merror, errno);
+ if (vector)
+ {
+ frontline(f, mag, p, result, merror, errno, args , name);
+ }
+}
+int redo;
+
+_DEFUN(run_vector_1,(vector, p, func, name, args),
+ int vector _AND
+ one_line_type *p _AND
+ char *func _AND
+ char *name _AND
+ char *args)
+{
+ FILE *f;
+ int mag;
+ double result;
+
+ if (vector)
+ {
+
+ VECOPEN(name, f);
+
+ if (redo)
+ {
+ double k;
+
+ for (k = -.2; k < .2; k+= 0.00132)
+ {
+
+ fprintf(f,"{1,1, 1,1, 0,0,0x%08x,0x%08x, 0x%08x, 0x%08x},\n",
+ k,k+4);
+
+ }
+
+ for (k = -1.2; k < 1.2; k+= 0.01)
+ {
+
+ fprintf(f,"{1,1, 1,1, 0,0,0x%08x,0x%08x, 0x%08x, 0x%08x},\n",
+ k,k+4);
+
+ }
+ for (k = -M_PI *2; k < M_PI *2; k+= M_PI/2)
+ {
+
+ fprintf(f,"{1,1, 1,1, 0,0,0x%08x,0x%08x, 0x%08x, 0x%08x},\n",
+ k,k+4);
+
+ }
+
+ for (k = -30; k < 30; k+= 1.7)
+ {
+
+ fprintf(f,"{2,2, 1,1, 0,0, 0x%08x,0x%08x, 0x%08x, 0x%08x},\n",
+ k,k+4);
+
+ }
+ VECCLOSE(f, name, args);
+ return;
+ }
+ }
+
+ newfunc(name);
+ while (p->line)
+ {
+ double arg1 = thedouble(p->qs[1].msw, p->qs[1].lsw);
+ double arg2 = thedouble(p->qs[2].msw, p->qs[2].lsw);
+
+ double r;
+ double rf;
+
+ errno = 0;
+ merror = 0;
+ mname = 0;
+
+
+ line(p->line);
+
+ merror = 0;
+ errno = 123;
+
+ if (strcmp(args,"dd")==0)
+ {
+ typedef double _EXFUN((*pdblfunc),(double));
+
+ /* Double function returning a double */
+
+ result = ((pdblfunc)(func))(arg1);
+
+ finish(f,vector, result, p, args, name);
+ }
+ else if (strcmp(args,"ff")==0)
+ {
+ float arga;
+ double a;
+
+ typedef float _EXFUN((*pdblfunc),(float));
+
+ /* Double function returning a double */
+
+ if (arg1 < FLT_MAX )
+ {
+ arga = arg1;
+ result = ((pdblfunc)(func))(arga);
+ finish(f, vector, result, p,args, name);
+ }
+ }
+ else if (strcmp(args,"ddd")==0)
+ {
+ typedef double _EXFUN((*pdblfunc),(double,double));
+
+ result = ((pdblfunc)(func))(arg1,arg2);
+ finish(f, vector, result, p,args, name);
+ }
+ else if (strcmp(args,"fff")==0)
+ {
+ double a,b;
+
+ float arga;
+ float argb;
+
+ typedef float _EXFUN((*pdblfunc),(float,float));
+
+
+ if (arg1 < FLT_MAX && arg2 < FLT_MAX)
+ {
+ arga = arg1;
+ argb = arg2;
+ result = ((pdblfunc)(func))(arga, argb);
+ finish(f, vector, result, p,args, name);
+ }
+ }
+ else if (strcmp(args,"did")==0)
+ {
+ typedef double _EXFUN((*pdblfunc),(int,double));
+
+ result = ((pdblfunc)(func))((int)arg1,arg2);
+ finish(f, vector, result, p,args, name);
+ }
+ else if (strcmp(args,"fif")==0)
+ {
+ double a,b;
+
+ float arga;
+ float argb;
+
+ typedef float _EXFUN((*pdblfunc),(int,float));
+
+
+ if (arg1 < FLT_MAX && arg2 < FLT_MAX)
+ {
+ arga = arg1;
+ argb = arg2;
+ result = ((pdblfunc)(func))((int)arga, argb);
+ finish(f, vector, result, p,args, name);
+ }
+ }
+
+ p++;
+ }
+ if (vector)
+ {
+ VECCLOSE(f, name, args);
+ }
+}
+
+void
+_DEFUN_VOID(test_math)
+{
+ test_acos(0);
+ test_acosf(0);
+ test_acosh(0);
+ test_acoshf(0);
+ test_asin(0);
+ test_asinf(0);
+ test_asinh(0);
+ test_asinhf(0);
+ test_atan(0);
+ test_atan2(0);
+ test_atan2f(0);
+ test_atanf(0);
+ test_atanh(0);
+ test_atanhf(0);
+ test_ceil(0);
+ test_ceilf(0);
+ test_cos(0);
+ test_cosf(0);
+ test_cosh(0);
+ test_coshf(0);
+ test_erf(0);
+ test_erfc(0);
+ test_erfcf(0);
+ test_erff(0);
+ test_exp(0);
+ test_expf(0);
+ test_fabs(0);
+ test_fabsf(0);
+ test_floor(0);
+ test_floorf(0);
+ test_fmod(0);
+ test_fmodf(0);
+ test_gamma(0);
+ test_gammaf(0);
+ test_hypot(0);
+ test_hypotf(0);
+ test_j0(0);
+ test_j0f(0);
+ test_j1(0);
+ test_j1f(0);
+ test_jn(0);
+ test_jnf(0);
+ test_log(0);
+ test_log10(0);
+ test_log10f(0);
+ test_log1p(0);
+ test_log1pf(0);
+ test_log2(0);
+ test_log2f(0);
+ test_logf(0);
+ test_sin(0);
+ test_sinf(0);
+ test_sinh(0);
+ test_sinhf(0);
+ test_sqrt(0);
+ test_sqrtf(0);
+ test_tan(0);
+ test_tanf(0);
+ test_tanh(0);
+ test_tanhf(0);
+ test_y0(0);
+ test_y0f(0);
+ test_y1(0);
+ test_y1f(0);
+ test_y1f(0);
+ test_ynf(0);
+}
+
+/* These have to be played with to get to compile on machines which
+ don't have the fancy <foo>f entry points
+*/
+
+#if 0
+float _DEFUN(cosf,(a), float a) { return cos((double)a); }
+float _DEFUN(sinf,(a), float a) { return sin((double)a); }
+float _DEFUN(log1pf,(a), float a) { return log1p((double)a); }
+float _DEFUN(tanf,(a), float a) { return tan((double)a); }
+float _DEFUN(ceilf,(a), float a) { return ceil(a); }
+float _DEFUN(floorf,(a), float a) { return floor(a); }
+#endif
+
+/*ndef HAVE_FLOAT*/
+#if 0
+
+float fmodf(a,b) float a,b; { return fmod(a,b); }
+float hypotf(a,b) float a,b; { return hypot(a,b); }
+
+float acosf(a) float a; { return acos(a); }
+float acoshf(a) float a; { return acosh(a); }
+float asinf(a) float a; { return asin(a); }
+float asinhf(a) float a; { return asinh(a); }
+float atanf(a) float a; { return atan(a); }
+float atanhf(a) float a; { return atanh(a); }
+
+float coshf(a) float a; { return cosh(a); }
+float erff(a) float a; { return erf(a); }
+float erfcf(a) float a; { return erfc(a); }
+float expf(a) float a; { return exp(a); }
+float fabsf(a) float a; { return fabs(a); }
+
+float gammaf(a) float a; { return gamma(a); }
+float j0f(a) float a; { return j0(a); }
+float j1f(a) float a; { return j1(a); }
+float log10f(a) float a; { return log10(a); }
+
+float logf(a) float a; { return log(a); }
+
+float sinhf(a) float a; { return sinh(a); }
+float sqrtf(a) float a; { return sqrt(a); }
+
+float tanhf(a) float a; { return tanh(a); }
+float y0f(a) float a; { return y0(a); }
+float y1f(a) float a; { return y1(a); }
+#endif