#include #include "test.h" #include #include #include int verbose; static int count; int inacc; int main (int ac, char **av) { int i; int math2 = 1; int string= 1; int is = 1; int math= 1; int cvt = 1; int ieee= 1; bt(); for (i = 1; i < ac; i++) { if (strcmp(av[i],"-v")==0) verbose ++; if (strcmp(av[i],"-nomath2") == 0) math2 = 0; if (strcmp(av[i],"-nostrin") == 0) string= 0; if (strcmp(av[i],"-nois") == 0) is = 0; if (strcmp(av[i],"-nomath") == 0) math= 0; if (strcmp(av[i],"-nocvt") == 0) cvt = 0; if (strcmp(av[i],"-noiee") == 0) ieee= 0; } if (cvt) test_cvt(); if (math2) test_math2(); if (string) test_string(); if (math) test_math(); if (is) test_is(); if (ieee) test_ieee(); printf("Tested %d functions, %d errors detected\n", count, inacc); return 0; } static const char *iname = "foo"; void newfunc (const char *string) { if (strcmp(iname, string)) { printf("testing %s\n", string); fflush(stdout); iname = string; } } static int theline; void line(li) int li; { if (verbose) { printf(" %d\n", li); } theline = li; count++; } int redo = 0; int reduce = 0; int strtod_vector = 0; int bigger (__ieee_double_shape_type *a, __ieee_double_shape_type *b) { if (a->parts.msw > b->parts.msw) { return 1; } else if (a->parts.msw == b->parts.msw) { if (a->parts.lsw > b->parts.lsw) { return 1; } } return 0; } /* Return the first bit different between two double numbers */ int mag_of_error (double is, double shouldbe) { __ieee_double_shape_type a,b; int i; int a_big; unsigned int mask; unsigned long int __x; unsigned long int msw, lsw; a.value = is; b.value = shouldbe; if (a.parts.msw == b.parts.msw && a.parts.lsw== b.parts.lsw) return 64; /* Subtract the larger from the smaller number */ a_big = bigger(&a, &b); if (!a_big) { int t; t = a.parts.msw; a.parts.msw = b.parts.msw; b.parts.msw = t; t = a.parts.lsw; a.parts.lsw = b.parts.lsw; b.parts.lsw = t; } __x = (a.parts.lsw) - (b.parts.lsw); msw = (a.parts.msw) - (b.parts.msw) - (__x > (a.parts.lsw)); lsw = __x; /* Find out which bit the difference is in */ mask = 0x80000000; for (i = 0; i < 32; i++) { if (((msw) & mask)!=0) return i; mask >>=1; } mask = 0x80000000; for (i = 0; i < 32; i++) { if (((lsw) & mask)!=0) return i+32; mask >>=1; } return 64; } int ok_mag; void test_sok (char *is, char *shouldbe) { if (strcmp(is,shouldbe)) { printf("%s:%d, inacurate answer: (%s should be %s)\n", iname, theline, is, shouldbe); inacc++; } } void test_iok (int is, int shouldbe) { if (is != shouldbe){ printf("%s:%d, inacurate answer: (%08x should be %08x)\n", iname, theline, is, shouldbe); inacc++; } } /* Compare counted strings upto a certain length - useful to test single prec float conversions against double results */ void test_scok (char *is, char *shouldbe, int count) { if (strncmp(is,shouldbe, count)) { printf("%s:%d, inacurate answer: (%s should be %s)\n", iname, theline, is, shouldbe); inacc++; } } void test_eok (int is, int shouldbe) { if (is != shouldbe){ printf("%s:%d, bad errno answer: (%d should be %d)\n", iname, theline, is, shouldbe); inacc++; } } void test_mok (double value, double shouldbe, int okmag) { __ieee_double_shape_type a,b; int mag = mag_of_error(value, shouldbe); if (mag == 0) { /* error in the first bit is ok if the numbers are both 0 */ if (value == 0.0 && shouldbe == 0.0) return; } a.value = shouldbe; b.value = value; if (mag < okmag) { printf("%s:%d, wrong answer: bit %d ", iname, theline, mag); printf("%08x%08x %08x%08x) ", a.parts.msw, a.parts.lsw, b.parts.msw, b.parts.lsw); printf("(%g %g)\n", a.value, b.value); inacc++; } } #ifdef __PCCNECV70__ kill() {} getpid() {} #endif bt(){ double f1,f2; f1 = 0.0; f2 = 0.0/f1; printf("(%g)\n", f2); }