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