File: math-bits.5c

package info (click to toggle)
nickle 2.107
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 3,756 kB
  • sloc: ansic: 27,954; yacc: 1,874; lex: 954; sh: 204; makefile: 13; lisp: 1
file content (86 lines) | stat: -rw-r--r-- 1,832 bytes parent folder | download
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
/*
 * Nickle test suite
 *
 * Trig operator tests
 */

load "math-tables.5c"

int test_precision = 333;
int errors = 0;
real error_bound = 1e-70;

real checked(real(real) f, real a) {
	try {
		real r = f(imprecise (a, test_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, test_precision), imprecise(b, test_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) * error_bound)
			return;
		if (abs(correct) < 1 && error < error_bound)
			return;
		printf ("error %v value %v\n", error, value);
	}
	if (value != correct) {
		printf ("check failed %s(%v) (was %.-g, should be %.-g)\n",
			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) * error_bound)
			return;
		if (abs(correct) < 1 && error < error_bound)
			return;
		printf ("error %v value %v\n", error, value);
	}
	if (value != correct) {
		printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)\n",
			op, input1, input2, value, correct);
		errors++;
	}
}