102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj/* Program to check that the FP stuff underlying these common FP
302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   functions isn't too badly broken.  Carefully kludged to print the
402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   same answers on different platforms (even when run natively). */
502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj#include <stdio.h>
702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj#include <math.h>
802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardjint main ( void )
1002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj{
1102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   double d;
1202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   float f;
1302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   int i;
1402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
1502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   const double tinyD = 0.0000000001;
1602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   const double tinyF = 0.0001;
1702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
1802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   /* -------------------- any arg -------------------- */
1902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
2002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
2102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
2202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("floorD(%+20.13e) = %+20.13e\n", d, floor(d));
2302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
2402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
2502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
2602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
2702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("floorF(%+20.4e) = %+20.4e\n", (double)f, (double)floorf(f));
2802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
2902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
3002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
3102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
3202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
3302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
3402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" ceilD(%+20.13e) = %+20.13e\n", d, ceil(d));
3502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
3602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
3702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
3802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
3902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" ceilF(%+20.4e) = %+20.4e\n", (double)f, (double)ceilf(f));
4002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
4102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
4202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
4302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
4402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
4502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
4602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  sinD(%+20.13e) = %+20.13e\n", d, sin(d));
4702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
4802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
4902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
5002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
5102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  sinF(%+20.4e) = %+20.4e\n", (double)f, (double)sinf(f));
5202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
5302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
5402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
5502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
5602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
5702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
5802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  cosD(%+20.13e) = %+20.13e\n", d, cos(d));
5902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
6002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
6102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
6202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
6302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  cosF(%+20.4e) = %+20.4e\n", (double)f, (double)cosf(f));
6402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
6502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
6602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
6702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
6802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
6902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
7002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  tanD(%+20.13e) = %+20.13e\n", d, tan(d));
7102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
7202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
7302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
7402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
7502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  tanF(%+20.4e) = %+20.4e\n", (double)f, (double)tanf(f));
7602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
7702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
7802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
7902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
8002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -2.0;
8102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
8202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  expD(%+20.13e) = %+20.13e\n", d, exp(d));
8302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
8402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
8502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -2.0;
8602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 41; i++) {
8702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  expF(%+20.4e) = %+20.4e\n", (double)f, (double)expf(f));
8802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
8902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
9002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
9102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   /* -------------------- >= 0 arg -------------------- */
9202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
9302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = 0.0;
9402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
9502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" sqrtD(%+20.13e) = %+20.13e\n", d, sqrt(d));
9602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
9702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
9802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = 0.0;
9902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
10002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" sqrtF(%+20.4e) = %+20.4e\n", (double)f, (double)sqrtf(f));
10102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
10202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
10302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
10402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
10502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = 0.0;
10602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
10702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  logD(%+20.13e) = %+20.13e\n", d, log(d));
10802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
10902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
11002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = 0.0;
11102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
11202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("  logF(%+20.4e) = %+20.4e\n", (double)f, (double)logf(f));
11302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
11402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
11502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
11602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
11702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = 0.0;
11802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
11902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("log10D(%+20.13e) = %+20.13e\n", d, log10(d));
12002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
12102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
12202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = 0.0;
12302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
12402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("log10F(%+20.4e) = %+20.4e\n", (double)f, (double)log10f(f));
12502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
12602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
12702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
12802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   /* -------------------- -1 .. +1 arg -------------------- */
12902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
13002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -1.0;
13102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
13202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" asinD(%+20.13e) = %+20.13e\n", d, asin(d));
13302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
13402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
13502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -1.0;
13602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
13702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" asinF(%+20.4e) = %+20.4e\n", (double)f, (double)asinf(f));
13802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
13902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
14002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
14102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   /* acos(double) seems very prone to accuracy loss near the end of
14202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      the range (arg --> +1.0).  Hence is different from the rest to
14302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      stop it getting so close to 1.0. */
14402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -1.0;
14502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
14602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" acosD(%+20.13e) = %+20.10e\n", d, acos(d));
14702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1 - 1000.0*tinyD;
14802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
14902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -1.0;
15002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
15102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" acosF(%+20.4e) = %+20.4e\n", (double)f, (double)acosf(f));
15202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
15302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
15402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
15502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
15602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -1.0;
15702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
15802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" atanD(%+20.13e) = %+20.13e\n", d, atan(d));
15902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
16002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
16102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -1.0;
16202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
16302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf(" atanF(%+20.4e) = %+20.4e\n", (double)f, (double)atanf(f));
16402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
16502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
16602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
16702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
16802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   d = -1.0;
16902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
17002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("atan2D(%+20.13e) = %+20.13e\n", d, atan2(d, 1.0));
17102fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      d += 0.1-tinyD;
17202fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
17302fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   f = -1.0;
17402fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   for (i = 0; i < 21; i++) {
17502fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      printf("atan2F(%+20.4e) = %+20.4e\n", (double)f, (double)atan2f(f,1.0));
17602fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj      f += 0.1-tinyF;
17702fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   }
17802fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj
17902fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj   return 0;
18002fd0d726c91e600817b5a2e41a6ea25f93b28fbsewardj}
181