t19.c revision 1.4
1/* $OpenBSD: t19.c,v 1.4 2017/11/29 14:31:50 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 22int scale[] = { 1, 2, 3, 10, 15, 20, 30}; 23long 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 26struct func {const char *name; long double (*f)(long double);}; 27 28struct 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 37int 38main(void) 39{ 40 int ret, si, ni, fi; 41 int status = 0; 42 43 for (si = 0; si < nitems(scale); si++) { 44 for (ni = 0; ni < nitems(num); ni++) { 45 for (fi = 0; fi < nitems(funcs); fi++) { 46 char cmd[100]; 47 FILE *fp; 48 long double v, d1, d2, diff, prec; 49 50 v = num[ni]; 51 if (v == 0.0 && funcs[fi].f == logl) 52 continue; 53 snprintf(cmd, sizeof(cmd), 54 "bc -l -e scale=%d -e '%s(%.19Lf)' -equit", 55 scale[si], funcs[fi].name, v); 56 fp = popen(cmd, "r"); 57 ret = fscanf(fp, "%Lf", &d1); 58 pclose(fp); 59 d2 = funcs[fi].f(v); 60 diff = fabsl(d1 - d2); 61 prec = powl(10.0L, (long double)-scale[si]); 62 if (prec < LDBL_EPSILON) 63 prec = LDBL_EPSILON; 64 prec *= 2; 65 /* XXX cheating ? */ 66 if (funcs[fi].f == logl) 67 prec *= 4; 68 else if (funcs[fi].f == expl) 69 prec *= 8; 70 if (diff > prec) { 71 printf("%s %d %Le %Le %Le %Le %Le\n", 72 funcs[fi].name, scale[si], 73 v, d1, d2, diff, prec); 74 status = 1; 75 } 76 77 } 78 } 79 } 80 return status; 81} 82