1 /* $OpenBSD: t19.c,v 1.2 2012/03/13 10:34:04 otto Exp $ */ 2 3 /* 4 * Copyright (c) 2012 Otto Moerbeek <otto@drijf.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 #include <float.h> 19 #include <math.h> 20 #include <stdio.h> 21 22 int scale[] = { 1, 2, 3, 10, 15, 20, 30}; 23 long double num[] = {-10, -M_PI, -3, -2, -1, -0.5, -0.01, 0, 0.01, 24 0.5, 1, 2, 3, M_PI, 10}; 25 26 struct func {const char *name; long double (*f)(long double);}; 27 28 struct func funcs[] = { {"s", sinl}, 29 {"c", cosl}, 30 {"e", expl}, 31 {"l", logl}, 32 {"a", atanl} 33 }; 34 35 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 36 37 main() 38 { 39 int ret, si, ni, fi; 40 int status = 0; 41 42 for (si = 0; si < nitems(scale); si++) { 43 for (ni = 0; ni < nitems(num); ni++) { 44 for (fi = 0; fi < nitems(funcs); fi++) { 45 char cmd[100]; 46 FILE *fp; 47 long double v, d1, d2, diff, prec; 48 49 v = num[ni]; 50 if (v == 0.0 && funcs[fi].f == logl) 51 continue; 52 snprintf(cmd, sizeof(cmd), 53 "bc -l -e scale=%d -e '%s(%.19Lf)' -equit", 54 scale[si], funcs[fi].name, v); 55 fp = popen(cmd, "r"); 56 ret = fscanf(fp, "%Lf", &d1); 57 pclose(fp); 58 d2 = funcs[fi].f(v); 59 diff = fabsl(d1 - d2); 60 prec = pow(10, -scale[si]); 61 if (prec < LDBL_EPSILON) 62 prec = LDBL_EPSILON; 63 prec *= 2; 64 /* XXX cheating ? */ 65 if (funcs[fi].f == logl) 66 prec *= 4; 67 else if (funcs[fi].f == expl) 68 prec *= 8; 69 if (diff > prec) { 70 printf("%s %d %Le %Le %Le %Le %Le\n", 71 funcs[fi].name, scale[si], 72 v, d1, d2, diff, prec); 73 status = 1; 74 } 75 76 } 77 } 78 } 79 return status; 80 } 81