1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
* Nickle test suite
*
* Trig operator tests
*/
load "math-tables.5c"
int precision = 64;
int errors = 0;
real checked(real(real) f, real a) {
try {
real r = f(imprecise (a, precision));
if (r > 1e10)
return 9999;
if (r < -1e10)
return 9999;
return r;
} catch invalid_argument(string type, int i, real v) {
return 10000;
}
return 0;
}
real checked2(real(real, real) f, real a, real b) {
try {
real r = f(imprecise(a, precision), imprecise(b, precision));
/* Just return the same value for large magnitudes
* as small variations in input cause the sign to flip
*/
if (r > 1e10)
return 9999;
if (r < -1e10)
return 9999;
return r;
} catch invalid_argument(string type, int i, real v) {
return 10000;
}
return 0;
}
void check(string op, real(real) f, real input, real correct)
{
real value = checked(f, input);
if (is_number (value))
{
real error = abs (value - correct);
if (abs(correct) >= 1 && error < abs(correct) * 1e-8)
return;
if (abs(correct) < 1 && error < 1e-8)
return;
printf ("error %v value %v\n", error, value);
}
if (value != correct) {
printf ("check failed %s(%v) (was %.-g, should be %.-g)",
op, input, value, correct);
errors++;
}
}
void check2(string op, real(real, real) f, real input1, real input2, real correct)
{
real value = checked2(f, input1, input2);
if (is_number (value))
{
real error = abs (value - correct);
if (abs(correct) >= 1 && error < abs(correct) * 1e-10)
return;
if (abs(correct) < 1 && error < 1e-10)
return;
printf ("error %v value %v\n", error, value);
}
if (value != correct) {
printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)",
op, input1, input2, value, correct);
errors++;
}
}
void check_sin_cos()
{
for (int i = 0; i < dim(sin_cos_table); i++) {
real angle = sin_cos_table[i].angle;
real sin_value = sin_cos_table[i].sin;
real cos_value = sin_cos_table[i].cos;
check("sin", sin, angle, sin_value);
check("cos", cos, angle, cos_value);
}
for (int i = 0; i < dim(asin_acos_table); i++) {
real ratio = asin_acos_table[i].ratio;
real asin_value = asin_acos_table[i].asin;
real acos_value = asin_acos_table[i].acos;
check("asin", asin, ratio, asin_value);
check("acos", acos, ratio, acos_value);
}
}
void check_tan()
{
for (int i = 0; i < dim(tan_table); i++) {
real angle = tan_table[i].angle;
real tan_value = tan_table[i].tan;
check("tan", tan, angle, tan_value);
}
for (int i = 0; i < dim(atan_table); i++) {
real ratio = atan_table[i].ratio;
real atan_value = atan_table[i].atan;
check("atan", atan, ratio, atan_value);
}
for (int i = 0; i < dim(atan2_table); i++) {
real y = atan2_table[i].y;
real x = atan2_table[i].x;
real atan2_value = atan2_table[i].atan2;
check2("atan2", atan2, y, x, atan2_value);
}
}
void check_log()
{
for (int i = 0; i < dim(log_table); i++) {
real in = log_table[i].in;
real log_value = log_table[i].log;
check("log", log, in, log_value);
}
for (int i = 0; i < dim(exp_table); i++) {
real in = exp_table[i].in;
real exp_value = exp_table[i].exp;
check("exp", exp, in, exp_value);
}
}
check_sin_cos();
check_tan();
check_log();
exit (errors);
|