1#!/usr/bin/nickle
2
3# Use nickle's extended precision floating point implementation
4# to generate some simple test vectors for long double math functions
5
6typedef struct  {
7	real(real a) f;
8	string name;
9} func_f_f_t;
10
11typedef struct  {
12	real(real a, real b) f;
13	string name;
14} func_f_ff_t;
15
16typedef struct  {
17	real(real a, real b, real c) f;
18	string name;
19} func_f_fff_t;
20
21typedef struct  {
22	real(real a, int b) f;
23	string name;
24} func_f_fi_t;
25
26typedef struct  {
27	int(real a) f;
28	string name;
29} func_i_f_t;
30
31string[] limited_funcs = {
32	"ceill",
33	"copysignl",
34	"fabsl",
35	"floorl",
36	"fmaxl",
37	"fminl",
38	"frexpl",
39	"hypotl",
40	"ilogbl",
41	"ldexpl",
42	"logbl",
43	"llrintl",
44	"lrintl",
45	"lroundl",
46	"llroundl",
47	"nanl",
48	"nearbyintl",
49	"rintl",
50	"roundl",
51	"scalbnl",
52	"scalblnl",
53	"truncl",
54	"logbl",
55	"sqrtl",
56};
57
58bool
59is_full_func(string name)
60{
61	for (int i = 0; i < dim(limited_funcs); i++)
62		if (limited_funcs[i] == name)
63			return false;
64	return true;
65}
66
67exception infinity(real v);
68exception nan();
69
70int prec = 512;
71int out_prec = 192;
72
73string
74toupper(string s)
75{
76	string o = "";
77	for (int i = 0; i < String::length(s); i++) {
78		int c = s[i];
79		if ('a' <= c && c <= 'z')
80			c = c - 'a' + 'A';
81		o = o + String::new(c);
82	}
83	return o;
84}
85
86string
87make_prec(string name)
88{
89	string prec = toupper(name) + "_PREC";
90	printf("#ifndef %s\n", prec);
91	printf("#define %s DEFAULT_PREC\n", prec);
92	printf("#endif\n");
93	return prec;
94}
95
96void
97gen_real_f_f(func_f_f_t f)
98{
99	real x, y;
100	string vec = sprintf("%s_vec", f.name);
101	printf("\n");
102	if (is_full_func(f.name))
103		printf("#ifdef FULL_LONG_DOUBLE\n");
104	string prec_name = make_prec(f.name);
105	printf("long_double_test_f_f_t %s[] = {\n", vec);
106	for (x = -10; x <= 10; x += .1) {
107		try {
108			string sy;
109			try {
110				try {
111					y = imprecise(f.f(imprecise(x, prec)), out_prec);
112					sy = sprintf("%.-eL", y);
113				} catch divide_by_zero(real x, real y) {
114					if (x == 0)
115						raise invalid_argument(f.name, 0, x);
116					raise infinity(x);
117				}
118			} catch infinity(real v) {
119				sy = "(long double) INFINITY";
120				if (v < 0)
121					sy = "-" + sy;
122			} catch nan() {
123				sy = "(long double) NAN";
124			}
125			printf("    { .line = __LINE__, .x = %.-eL, .y = %s },\n", x, sy);
126		} catch invalid_argument(string s, int i, poly x) {
127		}
128	}
129	printf("};\n\n");
130	printf("int test_%s(void) {\n", f.name);
131	printf("    unsigned int i;\n");
132	printf("    int result = 0;\n");
133	printf("    for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec);
134	printf("        long double y = %s(%s[i].x);\n", f.name, vec);
135	printf("        result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec, prec_name, vec);
136	printf("    }\n");
137	printf("    return result;\n");
138	printf("}\n");
139	if (is_full_func(f.name))
140		printf("#endif /* FULL_LONG_DOUBLE */\n");
141}
142
143real cbrt(real x) { return x**(1/3); }
144real exp10(real x) { return 10**x; }
145real exp2(real x) { return 2**x; }
146real expm1(real x) {
147	x = imprecise(x);
148	int bits = precision(x);
149	int obits = bits;
150
151	if (0 < x && x < 1)
152		obits -= exponent(x);
153
154	x = imprecise(x, obits);
155
156	return imprecise(exp(x) - 1, bits);
157}
158real lgamma(real x) {
159	if (x < 0 && x == floor(x))
160		raise infinity(1);
161	return log(gamma(x));
162}
163real log1p(real x) { return log(1+x); }
164real logb(real x) {
165	if (x == 0)
166		raise infinity(-1);
167	return exponent(imprecise(x)) - 1;
168}
169real pow10(real x) { return 10**x; }
170
171real round(x) { if (x < 0) return -round(-x); return floor(x+0.5); }
172real trunc(x) { if (x < 0) return -trunc(-x); return floor(x); }
173
174real acosh(x) {
175	if (x < 1)
176		raise nan();
177	return log(x + sqrt(x*x-1));
178}
179
180real asinh(x) {
181	if (x == 0) return 0;
182	real sign = 1;
183	if (x < 0) {
184		sign = -1;
185		x = -x;
186	}
187	return sign * log(x + sqrt(x*x+1));
188}
189
190real atanh(x) {
191	if (abs(x) > 1)
192		raise nan();
193	if (abs(x) == 1)
194		raise infinity(x);
195	return 0.5 * log((1 + x) / (1 - x));
196}
197
198real cosh(x) {
199	return (exp(x) + exp(-x)) / 2;
200}
201
202real sinh(x) {
203	return (exp(x) - exp(-x)) / 2;
204}
205
206real tanh(x) {
207	return sinh(x) / cosh(x);
208}
209
210real tgamma(real x) {
211	if (x == 0)
212		raise infinity(1);
213	if (x < 0 && x == floor(x))
214		raise nan();
215	return gamma(x);
216}
217
218real nearbyint(real x) {
219	real y;
220
221	if (x < 0)
222		y = ceil(x-0.5);
223	else
224		y = floor(x+0.5);
225	if (abs(x-y) == 0.5) {
226		if (y % 2 != 0) {
227			if (y > 0)
228				y--;
229			else
230				y++;
231		}
232	}
233	return y;
234}
235
236real _erf(real x, real off)
237{
238	x = imprecise(x);
239	int bits = precision(x);
240	int obits = bits + 512;
241	real factor = 2 / sqrt(pi_value(obits));
242
243	x = imprecise(x, obits);
244	off = imprecise(off, obits) / factor;
245	real val = x - off;
246
247	for (int n = 1; ; n++) {
248		int f = 2 * n + 1;
249		real a = ((-1)**n * x**f) / (n! * f);
250		val += a;
251		if (exponent(val) - exponent(a) > obits)
252			break;
253	}
254	return imprecise(val * factor, bits);
255}
256
257real erf(real x)
258{
259	return _erf(x, 0);
260}
261
262real erfc(real x)
263{
264	return -_erf(x, 1);
265}
266
267real jn(real x, int n)
268{
269	x = imprecise(x);
270	int bits = precision(x);
271	int obits = bits + 512;
272
273	x = imprecise(x, obits);
274	real val = imprecise(0, obits);
275
276	for (int m = 0; ; m++) {
277		real a = ((-1)**m / (m! * gamma(m + n + 1))) * (x/2)**(2 * m + n);
278		val += a;
279		if (exponent(val) - exponent(a) > obits)
280			break;
281	}
282	return imprecise(val, bits);
283}
284
285real scalbnl(real x, int exp)
286{
287	return x * (2 ** exp);
288}
289
290real ldexpl(real x, int exp)
291{
292	return x * (2 ** exp);
293}
294
295real rintl(real x) {
296	return nearbyint(x);
297}
298
299real round_even(real x, int bits)
300{
301	int exp = exponent(x);
302	real mant = abs(mantissa(x)) * 2**bits;
303
304	int ipart = floor(mant);
305	real fpart = mant - ipart;
306
307	if (fpart == 0.5) {
308		if ((ipart & 1) != 0)
309			ipart++;
310	} else if (fpart > 0.5)
311		ipart++;
312
313	real ret = ipart * (2 ** (exp - bits));
314	if (x < 0)
315		ret = -ret;
316	return ret;
317}
318
319real j0(real x) = jn(x,0);
320real j1(real x) = jn(x,1);
321
322real default_prec = 1e-20;
323
324func_f_f_t[] funcs_f_f = {
325	{ .f = acosh, .name = "acoshl" },
326	{ .f = acos, .name = "acosl" },
327	{ .f = asinh, .name = "asinhl" },
328	{ .f = asin, .name = "asinl" },
329	{ .f = atanh, .name = "atanhl" },
330	{ .f = atan, .name = "atanl" },
331	{ .f = cbrt, .name = "cbrtl" },
332	{ .f = ceil, .name = "ceill" },
333	{ .f = cosh, .name = "coshl" },
334	{ .f = cos, .name = "cosl" },
335	{ .f = erfc, .name = "erfcl" },
336	{ .f = erf, .name = "erfl" },
337	{ .f = exp10, .name = "exp10l" },
338	{ .f = exp2, .name = "exp2l" },
339	{ .f = exp, .name = "expl" },
340	{ .f = expm1, .name = "expm1l" },
341	{ .f = floor, .name = "floorl" },
342#	{ .f = j0, .name = "j0l" },
343#	{ .f = j1, .name = "j1l" },
344#	{ .f = jn, .name = "jnl" },
345	{ .f = lgamma, .name = "lgammal" },
346	{ .f = log10, .name = "log10l" },
347	{ .f = log1p, .name = "log1pl" },
348	{ .f = log2, .name = "log2l" },
349	{ .f = logb, .name = "logbl" },
350	{ .f = log, .name = "logl" },
351	{ .f = nearbyint, .name = "nearbyintl" },
352#	{ .f = pow10, .name = "pow10l" },	/* an alias for exp10 */
353        { .f = rintl, .name = "rintl" },
354	{ .f = round, .name = "roundl" },
355	{ .f = sinh, .name = "sinhl" },
356	{ .f = sin, .name = "sinl" },
357	{ .f = sqrt, .name = "sqrtl" },
358	{ .f = tanh, .name = "tanhl" },
359	{ .f = tan, .name = "tanl" },
360	{ .f = tgamma, .name = "tgammal" },
361	{ .f = trunc, .name = "truncl" },
362#	{ .f = y0, .name = "y0l" },
363#	{ .f = y1, .name = "y1l" },
364#	{ .f = yn, .name = "ynl" },
365};
366
367void
368gen_real_f_ff(func_f_ff_t f)
369{
370	real x0, x1, y;
371	string vec = sprintf("%s_vec", f.name);
372
373	printf("\n");
374	if (is_full_func(f.name))
375		printf("#ifdef FULL_LONG_DOUBLE\n");
376	string prec_name = make_prec(f.name);
377	printf("long_double_test_f_ff_t %s[] = {\n", vec);
378	for (x0 = -4; x0 <= 4; x0 += .25) {
379		for (x1 = -4; x1 <= 4; x1 += 0.25) {
380			try {
381				string sy;
382				try {
383					try {
384						y = round_even(f.f(imprecise(x0, prec), imprecise(x1, prec)), out_prec);
385						sy = sprintf("%.-eL", y);
386					} catch divide_by_zero(real x, real y) {
387						if (x == 0)
388							raise invalid_argument(f.name, 0, x);
389						raise infinity(x);
390					}
391				} catch infinity(real v) {
392					sy = "(long double) INFINITY";
393					if (v < 0)
394						sy = "-" + sy;
395				} catch nan() {
396					sy = "(long double) NAN";
397				}
398				printf("    { .line = __LINE__, .x0 = %.-eL, .x1 = %.-eL, .y = %s },\n", x0, x1, sy);
399			} catch invalid_argument(string s, int i, poly x) {
400			}
401		}
402	}
403	printf("};\n\n");
404	printf("int test_%s(void) {\n", f.name);
405	printf("    unsigned int i;\n");
406	printf("    int result = 0;\n");
407	printf("    for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec);
408	printf("        long double y = %s(%s[i].x0, %s[i].x1);\n", f.name, vec, vec);
409	printf("        result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec);
410	printf("    }\n");
411	printf("    return result;\n");
412	printf("}\n");
413	if (is_full_func(f.name))
414		printf("#endif /* FULL_LONG_DOUBLE */\n");
415}
416
417void
418gen_real_f_fff(func_f_fff_t f)
419{
420	real x0, x1, x2,y;
421	string vec = sprintf("%s_vec", f.name);
422
423	printf("\n");
424	if (is_full_func(f.name))
425		printf("#ifdef FULL_LONG_DOUBLE\n");
426	string prec_name = make_prec(f.name);
427	printf("long_double_test_f_fff_t %s[] = {\n", vec);
428	for (x0 = -4; x0 <= 4; x0 += 0.6) {
429		for (x1 = -4; x1 <= 4; x1 += 0.6) {
430			for (x2 = -4; x2 <= 4; x2 += 0.6) {
431				try {
432					string sy;
433					try {
434						try {
435							y = imprecise(f.f(imprecise(x0, prec), imprecise(x1, prec), imprecise(x2, prec)), out_prec);
436							sy = sprintf("%.-eL", y);
437						} catch divide_by_zero(real x, real y) {
438							if (x == 0)
439								raise invalid_argument(f.name, 0, x);
440							raise infinity(x);
441						}
442					} catch infinity(real v) {
443						sy = "(long double) INFINITY";
444						if (v < 0)
445							sy = "-" + sy;
446					} catch nan() {
447						sy = "(long double) NAN";
448					}
449					printf("    { .line = __LINE__, .x0 = %.-eL, .x1 = %.-eL, .x2 = %.-eL, .y = %s },\n", x0, x1, x2, sy);
450				} catch invalid_argument(string s, int i, poly x) {
451				}
452			}
453		}
454	}
455	printf("};\n\n");
456	printf("int test_%s(void) {\n", f.name);
457	printf("    unsigned int i;\n");
458	printf("    int result = 0;\n");
459	printf("    for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec);
460	printf("        long double y = %s(%s[i].x0, %s[i].x1, %s[i].x2);\n", f.name, vec, vec, vec);
461	printf("        result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec);
462	printf("    }\n");
463	printf("    return result;\n");
464	printf("}\n");
465	if (is_full_func(f.name))
466		printf("#endif /* FULL_LONG_DOUBLE */\n");
467}
468
469real fmod(real x, real y) {
470	if (y == 0)
471		raise nan();
472	real n = x / y;
473	if (n < 0)
474		n = ceil(n);
475	else
476		n = floor(n);
477	return x - n * y;
478}
479real fdim(real x, real y) { return max(x-y, 0); }
480real fmax(real x, real y) { return max(x,y); }
481real fmin(real x, real y) { return min(x,y); }
482
483real hypot(real x, real y) { return sqrt(x*x + y*y); }
484
485/* Compute an IEEE remainder */
486real remainder(real x, real y) {
487	if (y == 0)
488		raise nan();
489	real q = x / y;
490	int n;
491	if (q < 0)
492		n = ceil(q - 0.5);
493	else
494		n = floor(q + 0.5);
495	if (abs(q-n) == 0.5) {
496		if (n % 2 != 0) {
497			if (n > 0)
498				n--;
499			else
500				n++;
501		}
502	}
503	return x - n * y;
504}
505
506real drem(real x, real y) {
507	return remainder (x, y);
508}
509
510real copysign(real x, real y) {
511	x = abs(x);
512	if (y < 0)
513		x = -x;
514	return x;
515}
516
517bool
518isoddint(real x) {
519	return x == floor(x) && (floor(x) & 1) == 1;
520}
521
522bool
523isevenint(real x) {
524	return x == floor(x) && (floor(x) & 1) == 0;
525}
526
527bool
528isint(real x) {
529	return x == floor(x);
530}
531
532/* Deal with the oddities of IEEE pow */
533real powl(real x, real y) {
534	if (x == 0 && isoddint(y) && y < 0)
535		raise infinity(1);
536	if (x == 0 && y < 0)
537		raise infinity(1);
538	if (x == 0 && y > 0)
539		return 0;
540	if (x == 1)
541		return 1;
542	if (y == 0)
543		return 1;
544	if (x < 0 && !isint(y))
545		raise nan();
546	return pow(x, y);
547}
548
549real scalb(real x, real y) {
550	if (!isint(y))
551		raise nan();
552	return x * 2 ** y;
553}
554
555/* Functions of the form f(x,y) */
556func_f_ff_t[] funcs_f_ff = {
557        { .f = atan2, .name = "atan2l" },
558        { .f = powl, .name = "powl" },
559        { .f = fmod, .name = "fmodl" },
560#        { .f = nextafter, .name = "nextafterl" },
561#        { .f = nexttoward, .name = "nexttowardl" },
562        { .f = fdim, .name = "fdiml" },
563        { .f = fmax, .name = "fmaxl" },
564        { .f = fmin, .name = "fminl" },
565	{ .f = hypot, .name = "hypotl" },
566	{ .f = scalb, .name = "scalbl" },
567        { .f = remainder, .name = "remainderl" },
568        { .f = drem, .name = "dreml" },
569        { .f = copysign, .name = "copysignl" },
570};
571
572real fma(real x, real y, real z)
573{
574	real t = x * y + z;
575
576	return imprecise(t, precision(x));
577}
578
579/* Functions of the form f(x,y,z) */
580func_f_fff_t[] funcs_f_fff = {
581        { .f = fma, .name = "fmal" },
582};
583
584void
585gen_real_f_fi(func_f_fi_t f)
586{
587	real x0, y;
588	int x1;
589	string vec = sprintf("%s_vec", f.name);
590
591	printf("\n");
592	if (is_full_func(f.name))
593		printf("#ifdef FULL_LONG_DOUBLE\n");
594	string prec_name = make_prec(f.name);
595	printf("long_double_test_f_fi_t %s[] = {\n", vec);
596	for (x0 = -4; x0 <= 4; x0 += .25) {
597		for (x1 = -16; x1 <= 16; x1 += 1) {
598			try {
599				string sy;
600				try {
601					try {
602						y = imprecise(f.f(imprecise(x0, prec), x1), out_prec);
603						sy = sprintf("%.-eL", y);
604					} catch divide_by_zero(real x, real y) {
605						if (x == 0)
606							raise invalid_argument(f.name, 0, x);
607						raise infinity(x);
608					}
609				} catch infinity(real v) {
610					sy = "(long double) INFINITY";
611					if (v < 0)
612						sy = "-" + sy;
613				} catch nan() {
614					sy = "(long double) NAN";
615				}
616				printf("    { .line = __LINE__, .x0 = %.-eL, .x1 = %d, .y = %s },\n", x0, x1, sy);
617			} catch invalid_argument(string s, int i, poly x) {
618			}
619		}
620	}
621	printf("};\n\n");
622	printf("int test_%s(void) {\n", f.name);
623	printf("    unsigned int i;\n");
624	printf("    int result = 0;\n");
625	printf("    for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec);
626	printf("        long double y = %s(%s[i].x0, %s[i].x1);\n", f.name, vec, vec);
627	printf("        result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec);
628	printf("    }\n");
629	printf("    return result;\n");
630	printf("}\n");
631	if (is_full_func(f.name))
632		printf("#endif /* FULL_LONG_DOUBLE */\n");
633}
634
635/* Functions of the form f(x,y) */
636func_f_fi_t[] funcs_f_fi = {
637	{ .f = ldexpl, .name = "ldexpl" },
638	{ .f = scalbnl, .name = "scalbnl" },
639};
640
641exception invalid_int(string y);
642
643void
644gen_real_i_f(func_i_f_t f)
645{
646	real x;
647	int y;
648	string vec = sprintf("%s_vec", f.name);
649
650	printf("\n");
651	if (is_full_func(f.name))
652		printf("#ifdef FULL_LONG_DOUBLE\n");
653	printf("long_double_test_i_f_t %s[] = {\n", vec);
654	for (x = -10; x <= 10; x += .1) {
655		try {
656			string sy;
657			try {
658				y = f.f(imprecise(x, prec));
659				sy = sprintf("%d", y);
660			} catch invalid_int(string s) {
661				sy = s;
662			}
663			printf("    { .line = __LINE__, .x = %.-eL, .y = %s },\n", x, sy);
664		} catch invalid_argument(string s, int i, poly x) {
665		}
666	}
667	printf("};\n\n");
668	printf("int test_%s(void) {\n", f.name);
669	printf("    unsigned int i;\n");
670	printf("    int result = 0;\n");
671	printf("    for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec);
672	printf("        long long y = %s(%s[i].x);\n", f.name, vec);
673	printf("        result += check_long_long(\"%s\", %s[i].line, %s[i].y, y);\n", f.name, vec, vec);
674	printf("    }\n");
675	printf("    return result;\n");
676	printf("}\n");
677	if (is_full_func(f.name))
678		printf("#endif /* FULL_LONG_DOUBLE */\n");
679}
680
681int finite(real x) {
682	return 1;
683}
684
685int ilogb(real x) {
686	if (x == 0)
687		raise invalid_int("FP_ILOGB0");
688	return exponent(imprecise(x)) - 1;
689}
690
691int isinf(real x) {
692	return 0;
693}
694
695int isnan(real x) {
696	return 0;
697}
698
699int lrint(real x) {
700	return rintl(x);
701}
702
703int lround(real x) {
704	int ix = floor(x);
705	real diff = x - ix;
706	if ((diff == 0.5) && (x > 0) || (diff > 0.5))
707		ix++;
708	return ix;
709}
710
711/* Functions of the form i(x) */
712func_i_f_t[] funcs_i_f = {
713	{ .f = finite, .name = "finitel" },
714	{ .f = ilogb, .name = "ilogb" },
715	{ .f = isinf, .name = "isinfl" },
716	{ .f = isnan, .name = "isnanl" },
717	{ .f = lrint, .name = "lrintl" },
718	{ .f = lrint, .name = "llrintl" },
719	{ .f = lround, .name = "lroundl" },
720	{ .f = lround, .name = "llroundl" },
721};
722
723
724/*
725 * These functions aren't tested yet
726 *
727 *  long double modfl (long double, long double *);
728 *  float nexttowardf (float, long double);
729 *  double nexttoward (double, long double);
730 *  long double nextowardl (long double, long double);
731 *  long double remquol (long double, long double, int *);
732 *  long double lgammal_r (long double, int *);
733 *  void sincosl (long double, long double *, long double *);
734 */
735
736void
737main()
738{
739	for (int i = 0; i < dim(funcs_i_f); i++)
740		gen_real_i_f(funcs_i_f[i]);
741
742	for (int i = 0; i < dim(funcs_f_fi); i++)
743		gen_real_f_fi(funcs_f_fi[i]);
744
745	for (int i = 0; i < dim(funcs_f_ff); i++)
746		gen_real_f_ff(funcs_f_ff[i]);
747
748	for (int i = 0; i < dim(funcs_f_f); i++)
749		gen_real_f_f(funcs_f_f[i]);
750
751	for (int i = 0; i < dim(funcs_f_fff); i++)
752		gen_real_f_fff(funcs_f_fff[i]);
753
754	printf("long_double_test_t long_double_tests[] = {\n");
755	for (int i = 0; i < dim(funcs_f_f); i++) {
756		if (is_full_func(funcs_f_f[i].name))
757			printf("#ifdef FULL_LONG_DOUBLE\n");
758		printf("    { .name = \"%s\", .test = test_%s },\n", funcs_f_f[i].name, funcs_f_f[i].name);
759		if (is_full_func(funcs_f_f[i].name))
760			printf("#endif /* FULL_LONG_DOUBLE */\n");
761	}
762	for (int i = 0; i < dim(funcs_f_ff); i++) {
763		if (is_full_func(funcs_f_ff[i].name))
764			printf("#ifdef FULL_LONG_DOUBLE\n");
765		printf("    { .name = \"%s\", .test = test_%s },\n", funcs_f_ff[i].name, funcs_f_ff[i].name);
766		if (is_full_func(funcs_f_ff[i].name))
767			printf("#endif /* FULL_LONG_DOUBLE */\n");
768	}
769	for (int i = 0; i < dim(funcs_f_fff); i++) {
770		if (is_full_func(funcs_f_fff[i].name))
771			printf("#ifdef FULL_LONG_DOUBLE\n");
772		printf("    { .name = \"%s\", .test = test_%s },\n", funcs_f_fff[i].name, funcs_f_fff[i].name);
773		if (is_full_func(funcs_f_fff[i].name))
774			printf("#endif /* FULL_LONG_DOUBLE */\n");
775	}
776	for (int i = 0; i < dim(funcs_f_fi); i++) {
777		if (is_full_func(funcs_f_fi[i].name))
778			printf("#ifdef FULL_LONG_DOUBLE\n");
779		printf("    { .name = \"%s\", .test = test_%s },\n", funcs_f_fi[i].name, funcs_f_fi[i].name);
780		if (is_full_func(funcs_f_fi[i].name))
781			printf("#endif /* FULL_LONG_DOUBLE */\n");
782	}
783	for (int i = 0; i < dim(funcs_i_f); i++) {
784		if (is_full_func(funcs_i_f[i].name))
785			printf("#ifdef FULL_LONG_DOUBLE\n");
786		printf("    { .name = \"%s\", .test = test_%s },\n", funcs_i_f[i].name, funcs_i_f[i].name);
787		if (is_full_func(funcs_i_f[i].name))
788			printf("#endif /* FULL_LONG_DOUBLE */\n");
789	}
790	printf("};\n");
791}
792
793main();
794