File: logtest.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 (66 lines) | stat: -rw-r--r-- 1,494 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
/*
 * Nickle test suite
 *
 * log test
 */
library "math-bits.5c"

void check_log()
{
	printf("Checking log precision\n");
	int log_errors = 0;
	for (int prec = 10; prec <= 1000; prec *= 10) {
		real eval = Math::e_value(prec);
		for (real x = imprecise(0.001, prec); x < 20; x *= 1.5) {
			real	lnx = log(x);

			real	explnx = exp(lnx);

			real	rterror = abs((x - explnx) / x);
			real	rtlimit = 2 ** (-(prec - 6));

			if (rterror > rtlimit) {
				printf("exp(log(x)) = x: prec %d error %g limit %g x %.-g\n",
				       prec, rterror, rtlimit, x);
				errors++;
			}

			for (real y = imprecise(0.001, prec); y < 20; y *= 1.5) {
				real	lny = log(y);

				if (sign (lnx) != sign(lny))
				    continue;

				real	lnxy = log(x * y);
				real	lnx_lny = lnx + lny;
				real	error = abs ((lnxy - lnx_lny) / lnxy);

				int plnxy = precision(lnxy);
				int plnx_lny = precision(lnx_lny);

				if (plnxy != plnx_lny)
					printf("precision difference %d %d\n",
					       plnxy, plnx_lny);

				int	bitdiff = max(2, ceil(abs(log2(abs(lnx)) - log2(abs(lny)))));

				real	limit = 2 ** -(prec - bitdiff - 5);

				if (error > limit) {
					printf("log(x*y) = log(x)+log(y): prec %d error %g limit %g x %.-g y %.-g\n",
					       prec, error, limit, x, y);
					errors++;
				}
			}
		}
	}
	printf("Checking log\n");
	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);
	}
}

check_log();
exit(errors);