xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/features/float (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1set	prototyped
2set	nooptimize
3set	stdio FEATURE/standards
4hdr	float,limits,math,values
5lib,npt	frexp,frexpl,ldexp,ldexpl,finite,finitel,isinfl,isnanl,copysign,copysignl FEATURE/standards math.h -lm
6lib	fpclassify -lm note{ fpclassify present and works }end link{
7		#include <sys/types.h>
8		#include <sys/stat.h>
9		#include <stdlib.h>
10		#include <unistd.h>
11		#include <math.h>
12		int main() { return fpclassify(-0.0); }
13	}end
14lib	isinf -lm note{ isinf present and works }end link{
15		#include <sys/types.h>
16		#include <sys/stat.h>
17		#include <stdlib.h>
18		#include <unistd.h>
19		#include <math.h>
20		int main() { return isinf(-0.0); }
21	}end
22lib	isnan -lm note{ isnan present and works }end link{
23		#include <sys/types.h>
24		#include <sys/stat.h>
25		#include <stdlib.h>
26		#include <unistd.h>
27		#include <math.h>
28		int main() { return isnan(-0.0); }
29	}end
30lib	signbit -lm note{ signbit present and works }end link{
31		#include <sys/types.h>
32		#include <sys/stat.h>
33		#include <stdlib.h>
34		#include <unistd.h>
35		#include <math.h>
36		int main() { return signbit(-0.0); }
37	}end
38
39tst	ast_no_um2fm note{ no unsigned intmax => floatmax cast }end nolink{
40	#include "FEATURE/common"
41	int
42	main()
43	{
44		_ast_fltmax_t		f = 0;
45		unsigned _ast_intmax_t	i = 0;
46		f = i;
47		i = f;
48		return f == i;
49	}
50}end
51
52tst	ast_mpy_overflow_fpe note{ fpe on mpy overflow }end noexecute{
53	int
54	main()
55	{
56		float	f;
57		float	p;
58		int	i;
59
60		i = 0;
61		p = f = 1.0;
62		do
63		{
64			p = f;
65			f *= 2.0;
66		} while (f != p && ++i < 1024);
67		return 0;
68	}
69}end
70
71tst	ast_div_underflow_fpe note{ fpe on div underflow }end noexecute{
72	int
73	main()
74	{
75		float	f;
76		float	p;
77		int	i;
78
79		i = 0;
80		p = f = 1.0;
81		do
82		{
83			p = f;
84			f /= 2.0;
85		} while (f != p && ++i < 1024);
86		return 0;
87	}
88}end
89
90macro{
91	#if _hdr_float
92	#include <float.h>
93	#endif
94	#if _hdr_limits
95	#include <limits.h>
96	#endif
97	#if _hdr_math
98	#include <math.h>
99	#endif
100	#if _hdr_values
101	#include <values.h>
102	#endif
103
104	#if !defined(FLT_MIN_EXP) && defined(FMINEXP)
105	#define FLT_MIN_EXP	FMINEXP
106	#endif
107	#if !defined(FLT_MIN) && defined(MINFLOAT)
108	#define FLT_MIN		MINFLOAT
109	#endif
110	#if !defined(FLT_MAX_EXP) && defined(FMAXEXP)
111	#define FLT_MAX_EXP	FMAXEXP
112	#endif
113	#if !defined(FLT_MAX) && defined(MAXFLOAT)
114	#define FLT_MAX		MAXFLOAT
115	#endif
116
117	#if !defined(DBL_MIN_EXP) && defined(DMINEXP)
118	#define DBL_MIN_EXP	DMINEXP
119	#endif
120	#if !defined(DBL_MIN) && defined(MINDOUBLE)
121	#define DBL_MIN		MINDOUBLE
122	#endif
123	#if !defined(DBL_MAX_EXP) && defined(DMAXEXP)
124	#define DBL_MAX_EXP	DMAXEXP
125	#endif
126	#if !defined(DBL_MAX) && defined(MAXDOUBLE)
127	#define DBL_MAX		MAXDOUBLE
128	#endif
129
130	<<"#include <ast_common.h>">>
131	#if _hdr_float
132	<<"#include <float.h>">>
133	#endif
134	#if _hdr_math
135	<<"#include <math.h>">>
136	#endif
137	#ifdef FLT_DIG
138	<<"#ifndef FLT_DIG">>
139	<<"#define FLT_DIG">>		FLT_DIG
140	<<"#endif">>
141	#endif
142	#ifdef FLT_MAX
143	<<"#ifndef FLT_MAX">>
144	<<"#define FLT_MAX">>		FLT_MAX
145	<<"#endif">>
146	#endif
147	#ifdef FLT_MAX_10_EXP
148	<<"#ifndef FLT_MAX_10_EXP">>
149	<<"#define FLT_MAX_10_EXP">>	FLT_MAX_10_EXP
150	<<"#endif">>
151	#endif
152	#ifdef FLT_MAX_EXP
153	<<"#ifndef FLT_MAX_EXP">>
154	<<"#define FLT_MAX_EXP">>	FLT_MAX_EXP
155	<<"#endif">>
156	#endif
157	#ifdef FLT_MIN
158	<<"#ifndef FLT_MIN">>
159	<<"#define FLT_MIN">>		FLT_MIN
160	<<"#endif">>
161	#endif
162	#ifdef FLT_MIN_10_EXP
163	<<"#ifndef FLT_MIN_10_EXP">>
164	<<"#define FLT_MIN_10_EXP">>	FLT_MIN_10_EXP
165	<<"#endif">>
166	#endif
167	#ifdef FLT_MIN_EXP
168	<<"#ifndef FLT_MIN_EXP">>
169	<<"#define FLT_MIN_EXP">>	FLT_MIN_EXP
170	<<"#endif">>
171	#endif
172
173	#ifdef DBL_DIG
174	<<"#ifndef DBL_DIG">>
175	<<"#define DBL_DIG">>		DBL_DIG
176	<<"#endif">>
177	#endif
178	#ifdef DBL_MAX
179	<<"#ifndef DBL_MAX">>
180	<<"#define DBL_MAX">>		DBL_MAX
181	<<"#endif">>
182	#endif
183	#ifdef DBL_MAX_10_EXP
184	<<"#ifndef DBL_MAX_10_EXP">>
185	<<"#define DBL_MAX_10_EXP">>	DBL_MAX_10_EXP
186	<<"#endif">>
187	#endif
188	#ifdef DBL_MAX_EXP
189	<<"#ifndef DBL_MAX_EXP">>
190	<<"#define DBL_MAX_EXP">>	DBL_MAX_EXP
191	<<"#endif">>
192	#endif
193	#ifdef DBL_MIN
194	<<"#ifndef DBL_MIN">>
195	<<"#define DBL_MIN">>		DBL_MIN
196	<<"#endif">>
197	#endif
198	#ifdef DBL_MIN_10_EXP
199	<<"#ifndef DBL_MIN_10_EXP">>
200	<<"#define DBL_MIN_10_EXP">>	DBL_MIN_10_EXP
201	<<"#endif">>
202	#endif
203	#ifdef DBL_MIN_EXP
204	<<"#ifndef DBL_MIN_EXP">>
205	<<"#define DBL_MIN_EXP">>	DBL_MIN_EXP
206	<<"#endif">>
207	#endif
208
209	#ifdef LDBL_DIG
210	<<"#ifndef LDBL_DIG">>
211	<<"#define LDBL_DIG">>		LDBL_DIG
212	<<"#endif">>
213	#endif
214	#ifdef LDBL_MAX
215	<<"#ifndef LDBL_MAX">>
216	<<"#define LDBL_MAX">>		LDBL_MAX
217	<<"#endif">>
218	#endif
219	#ifdef LDBL_MAX_10_EXP
220	<<"#ifndef LDBL_MAX_10_EXP">>
221	<<"#define LDBL_MAX_10_EXP">>	LDBL_MAX_10_EXP
222	<<"#endif">>
223	#endif
224	#ifdef LDBL_MAX_EXP
225	<<"#ifndef LDBL_MAX_EXP">>
226	<<"#define LDBL_MAX_EXP">>	LDBL_MAX_EXP
227	<<"#endif">>
228	#endif
229	#ifdef LDBL_MIN
230	<<"#ifndef LDBL_MIN">>
231	<<"#define LDBL_MIN">>		LDBL_MIN
232	<<"#endif">>
233	#endif
234	#ifdef LDBL_MIN_10_EXP
235	<<"#ifndef LDBL_MIN_10_EXP">>
236	<<"#define LDBL_MIN_10_EXP">>	LDBL_MIN_10_EXP
237	<<"#endif">>
238	#endif
239	#ifdef LDBL_MIN_EXP
240	<<"#ifndef LDBL_MIN_EXP">>
241	<<"#define LDBL_MIN_EXP">>	LDBL_MIN_EXP
242	<<"#endif">>
243	#endif
244}end
245
246tst	- note{ missing floating point limits }end output{
247	#include "FEATURE/common"
248	#include <stdio.h>
249	#if _hdr_float
250	#include <float.h>
251	#endif
252	#if _hdr_limits
253	#include <limits.h>
254	#endif
255	#if _hdr_math
256	#include <math.h>
257	#endif
258	#if _hdr_values
259	#include <values.h>
260	#endif
261	#include <signal.h>
262	#ifdef SIGFPE
263	static int caught = 0;
264	#if _STD_
265	static void catch(int sig)
266	#else
267	static void catch(sig) int sig;
268	#endif
269	{
270		signal(sig, SIG_IGN);
271		caught++;
272	}
273	#endif
274	int
275	main()
276	{
277		register int		i;
278		register int		s;
279		float			f;
280		float			pf;
281		float			mf;
282		float			xf;
283		double			d;
284		double			pd;
285		double			md;
286		char*			fp;
287	#if _ast_fltmax_double
288		char*			fs = "";
289		char*			ds = "";
290	#else
291		_ast_fltmax_t		l;
292		_ast_fltmax_t		pl;
293		_ast_fltmax_t		ml;
294		char*			fs = "F";
295		char*			ds = "";
296		char*			ls = "L";
297	#endif
298		unsigned long		u;
299		unsigned _ast_intmax_t	w;
300		unsigned _ast_intmax_t	pw;
301		unsigned _ast_intmax_t	x;
302		unsigned short		us;
303		unsigned int		ui;
304		unsigned long		ul;
305		unsigned _ast_intmax_t	uq;
306
307	#ifdef SIGFPE
308		signal(SIGFPE, catch);
309	#endif
310		printf("\n");
311		printf("\n");
312		us = 0;
313		us = ~us;
314		i = 0;
315		while (us /= 10)
316			i++;
317		printf("#define USHRT_DIG		%d\n", i);
318		ui = 0;
319		ui = ~ui;
320		i = 0;
321		while (ui /= 10)
322			i++;
323		printf("#define UINT_DIG		%d\n", i);
324		ul = 0;
325		ul = ~ul;
326		i = 0;
327		while (ul /= 10)
328			i++;
329		printf("#define ULONG_DIG		%d\n", i);
330		if (sizeof(uq) > sizeof(ul))
331		{
332			uq = 0;
333			uq = ~uq;
334			i = 0;
335			while (uq /= 10)
336				i++;
337			printf("#define ULLONG_DIG		%d\n", i);
338			printf("#define UINTMAX_DIG		ULLONG_DIG\n");
339		}
340		else
341			printf("#define UINTMAX_DIG		ULONG_DIG\n");
342		printf("\n");
343		w = 1;
344		do
345		{
346			pw = w;
347			w *= 2;
348			f = (_ast_intmax_t)w;
349			x = (_ast_intmax_t)f;
350		} while (w > pw && w == x);
351		w = (pw - 1) + pw;
352		u = ~0;
353		if (u > w)
354			u = w;
355		printf("#define FLT_ULONG_MAX		%lu.0F\n", u);
356		if (sizeof(w) > sizeof(u))
357		{
358			printf("#define FLT_ULLONG_MAX		%llu.0F\n", w);
359			printf("#define FLT_UINTMAX_MAX		FLT_ULLONG_MAX\n");
360		}
361		else
362		{
363			printf("#define FLT_ULLONG_MAX		FLT_ULONG_MAX\n");
364			printf("#define FLT_UINTMAX_MAX		FLT_ULONG_MAX\n");
365		}
366		u /= 2;
367		w /= 2;
368		printf("#define FLT_LONG_MAX		%lu.0F\n", u);
369		if (sizeof(w) > sizeof(u))
370		{
371			printf("#define FLT_LLONG_MAX		%llu.0F\n", w);
372			printf("#define FLT_INTMAX_MAX		FLT_LLONG_MAX\n");
373		}
374		else
375		{
376			printf("#define FLT_LLONG_MAX		FLT_LONG_MAX\n");
377			printf("#define FLT_INTMAX_MAX		FLT_LONG_MAX\n");
378		}
379		u++;
380		w++;
381		printf("#define FLT_LONG_MIN		(-%lu.0F)\n", u);
382		if (sizeof(w) > sizeof(u))
383		{
384			printf("#define FLT_LLONG_MIN		(-%llu.0F)\n", w);
385			printf("#define FLT_INTMAX_MIN		FLT_LLONG_MIN\n");
386		}
387		else
388		{
389			printf("#define FLT_LLONG_MIN		FLT_LONG_MIN\n");
390			printf("#define FLT_INTMAX_MIN		FLT_LONG_MIN\n");
391		}
392	#ifdef FLT_DIG
393		s = FLT_DIG;
394	#else
395		f = pf = 1.0;
396		s = -1;
397		do
398		{
399			s++;
400			f *= 10.0;
401		} while (f != (f + pf));
402	#endif
403	#if defined(FLT_MIN) && defined(FLT_MIN_EXP)
404		i = FLT_MIN_EXP;
405		mf = FLT_MIN;
406	#else
407		i = 3;
408		f = pf = 1.0;
409		do
410		{
411			i--;
412			mf = pf;
413			pf = f;
414			f /= 2.0;
415		} while (f < pf);
416	#ifdef FLT_MIN_EXP
417		i = FLT_MIN_EXP;
418	#endif
419	#ifdef FLT_MIN
420		mf = FLT_MIN;
421	#endif
422	#endif
423	#ifndef FLT_DIG
424		printf("#ifndef FLT_DIG\n");
425		printf("#define FLT_DIG			%d\n", s);
426		printf("#endif\n");
427	#endif
428	#ifndef FLT_MIN
429		printf("#ifndef FLT_MIN\n");
430		printf("#define FLT_MIN			%.*E%s\n", s + 1, mf, fs);
431		printf("#endif\n");
432	#endif
433	#ifndef FLT_MIN_EXP
434		printf("#ifndef FLT_MIN_EXP\n");
435		printf("#define FLT_MIN_EXP		(%d)\n", i);
436		printf("#endif\n");
437	#endif
438
439	#if defined(FLT_MAX) && defined(FLT_MAX_EXP)
440		i = FLT_MAX_EXP;
441		f = FLT_MAX;
442	#else
443		i = -1;
444		f = pf = 1.0;
445		do
446		{
447			i++;
448			mf = pf;
449			pf = f;
450			f *= 2.0;
451		} while (f > pf);
452	#ifdef FLT_MAX_EXP
453		i = FLT_MAX_EXP;
454	#endif
455	#ifdef FLT_MAX
456		f = FLT_MAX;
457	#endif
458	#endif
459	#ifdef FLT_MAX_EXP
460		i = FLT_MAX_EXP;
461	#else
462		f = 1;
463		do
464		{
465			f *= 2.0;
466		} while (mf == (mf + f));
467		f = (mf - f) * 2.0 + f;
468	#endif
469		xf = f;
470	#ifndef FLT_MAX
471		printf("#ifndef FLT_MAX\n");
472		printf("#define FLT_MAX			%.*E%s\n", s + 1, f, fs);
473		printf("#endif\n");
474	#endif
475	#ifndef FLT_MAX_EXP
476		printf("#ifndef FLT_MAX_EXP\n");
477		printf("#define FLT_MAX_EXP		%d\n", i);
478		printf("#endif\n");
479	#endif
480
481	#ifdef FLT_MIN_10_EXP
482		i = FLT_MIN_10_EXP;
483	#else
484		i = 2;
485		f = 1.0;
486		do
487		{
488			i--;
489			pf = f;
490			f /= 10.0;
491		} while (f < pf);
492	#endif
493	#ifndef FLT_MIN_10_EXP
494		printf("#ifndef FLT_MIN_10_EXP\n");
495		printf("#define FLT_MIN_10_EXP		(%d)\n", i);
496		printf("#endif\n");
497	#endif
498
499	#ifdef FLT_MAX_10_EXP
500		i = FLT_MAX_10_EXP;
501	#else
502		i = -2;
503		f = 1.0;
504		do
505		{
506			i++;
507			pf = f;
508			f *= 10.0;
509		} while (f > pf);
510	#endif
511	#ifndef FLT_MAX_10_EXP
512		printf("#ifndef FLT_MAX_10_EXP\n");
513		printf("#define FLT_MAX_10_EXP		%d\n", i);
514		printf("#endif\n");
515	#endif
516
517		printf("\n");
518		w = 1;
519		do
520		{
521			pw = w;
522			w *= 2;
523			d = (_ast_intmax_t)w;
524			x = (_ast_intmax_t)d;
525		} while (w > pw && w == x);
526		w = (pw - 1) + pw;
527		u = ~0;
528		if (u > w)
529			u = w;
530		printf("#define DBL_ULONG_MAX		%lu.0\n", u);
531		if (sizeof(w) > sizeof(u))
532		{
533			printf("#define DBL_ULLONG_MAX		%llu.0\n", w);
534			printf("#define DBL_UINTMAX_MAX		DBL_ULLONG_MAX\n");
535		}
536		else
537		{
538			printf("#define DBL_ULLONG_MAX		DBL_ULONG_MAX\n");
539			printf("#define DBL_UINTMAX_MAX		DBL_ULONG_MAX\n");
540		}
541		u /= 2;
542		w /= 2;
543		printf("#define DBL_LONG_MAX		%lu.0\n", u);
544		if (sizeof(w) > sizeof(u))
545		{
546			printf("#define DBL_LLONG_MAX		%llu.0\n", w);
547			printf("#define DBL_INTMAX_MAX		DBL_LLONG_MAX\n");
548		}
549		else
550		{
551			printf("#define DBL_LLONG_MAX		DBL_LONG_MAX\n");
552			printf("#define DBL_INTMAX_MAX		DBL_LONG_MAX\n");
553		}
554		u++;
555		w++;
556		printf("#define DBL_LONG_MIN		(-%lu.0)\n", u);
557		if (sizeof(w) > sizeof(u))
558		{
559			printf("#define DBL_LLONG_MIN		(-%llu.0)\n", w);
560			printf("#define DBL_INTMAX_MIN		DBL_LLONG_MIN\n");
561		}
562		else
563		{
564			printf("#define DBL_LLONG_MIN		DBL_LONG_MIN\n");
565			printf("#define DBL_INTMAX_MIN		DBL_LONG_MIN\n");
566		}
567	#ifdef DBL_DIG
568		s = DBL_DIG;
569	#else
570		d = pd = 1.0;
571		s = -1;
572		do
573		{
574			s++;
575			d *= 10.0;
576		} while (d != (d + pd));
577	#endif
578	#if defined(DBL_MIN) && defined(DBL_MIN_EXP)
579		i = DBL_MIN_EXP;
580		md = DBL_MIN;
581	#else
582		i = 3;
583		d = pd = 1.0;
584		do
585		{
586			i--;
587			md = pd;
588			pd = d;
589			d /= 2.0;
590		} while (d < pd);
591	#ifdef DBL_MIN_EXP
592		i = DBL_MIN_EXP;
593	#endif
594	#ifdef DBL_MIN
595		md = DBL_MIN;
596	#endif
597	#endif
598	#ifndef DBL_DIG
599		printf("#ifndef DBL_DIG\n");
600		printf("#define DBL_DIG			%d\n", s);
601		printf("#endif\n");
602	#endif
603	#ifndef DBL_MIN
604		printf("#ifndef DBL_MIN\n");
605		printf("#define DBL_MIN			%.*E%s\n", s + 1, md, ds);
606		printf("#endif\n");
607	#endif
608	#ifndef DBL_MIN_EXP
609		printf("#ifndef DBL_MIN_EXP\n");
610		printf("#define DBL_MIN_EXP		(%d)\n", i);
611		printf("#endif\n");
612	#endif
613
614	#if defined(DBL_MAX) && defined(DBL_MAX_EXP)
615		i = DBL_MAX_EXP;
616		d = DBL_MAX;
617	#else
618		i = -1;
619		d = pd = 1.0;
620		do
621		{
622			i++;
623			md = pd;
624			pd = d;
625			d *= 2.0;
626		} while (d > pd);
627		d = 1.0;
628		do
629		{
630			d *= 2.0;
631		} while (md == (md + d));
632		d = (md - d) * 2.0 + d;
633	#ifdef DBL_MAX_EXP
634		i = DBL_MAX_EXP;
635	#endif
636	#ifdef DBL_MAX
637		d = DBL_MAX;
638	#endif
639	#endif
640	#ifndef DBL_MAX
641		printf("#ifndef DBL_MAX\n");
642		printf("#define DBL_MAX			%.*E%s\n", s + 1, d, ds);
643		printf("#endif\n");
644	#endif
645	#ifndef DBL_MAX_EXP
646		printf("#ifndef DBL_MAX_EXP\n");
647		printf("#define DBL_MAX_EXP		%d\n", i);
648		printf("#endif\n");
649	#endif
650
651	#ifdef DBL_MIN_10_EXP
652		i = DBL_MIN_10_EXP;
653	#else
654		i = 2;
655		d = 1.0;
656		do
657		{
658			i--;
659			pd = d;
660			d /= 10.0;
661		} while (d < pd);
662	#endif
663	#ifndef DBL_MIN_10_EXP
664		printf("#ifndef DBL_MIN_10_EXP\n");
665		printf("#define DBL_MIN_10_EXP		(%d)\n", i);
666		printf("#endif\n");
667	#endif
668
669	#ifdef DBL_MAX_10_EXP
670		i = DBL_MAX_10_EXP;
671	#else
672		i = -2;
673		d = 1.0;
674		do
675		{
676			i++;
677			pd = d;
678			d *= 10.0;
679		} while (d > pd);
680	#endif
681	#ifndef DBL_MAX_10_EXP
682		printf("#ifndef DBL_MAX_10_EXP\n");
683		printf("#define DBL_MAX_10_EXP		%d\n", i);
684		printf("#endif\n");
685	#endif
686
687	#if !_ast_fltmax_double
688		printf("\n");
689		w = 1;
690		do
691		{
692			pw = w;
693			w *= 2;
694			l = (_ast_intmax_t)w;
695			x = (_ast_intmax_t)l;
696		} while (w > pw && w == x);
697		w = (pw - 1) + pw;
698		u = ~0;
699		if (u > w)
700			u = w;
701		printf("#define LDBL_ULONG_MAX		%lu.0L\n", u);
702		if (sizeof(w) > sizeof(u))
703		{
704			printf("#define LDBL_ULLONG_MAX		%llu.0L\n", w);
705			printf("#define LDBL_UINTMAX_MAX	LDBL_ULLONG_MAX\n");
706		}
707		else
708		{
709			printf("#define LDBL_ULLONG_MAX		LDBL_ULONG_MAX\n");
710			printf("#define LDBL_UINTMAX_MAX	LDBL_ULONG_MAX\n");
711		}
712		u /= 2;
713		w /= 2;
714		printf("#define LDBL_LONG_MAX		%lu.0L\n", u);
715		if (sizeof(w) > sizeof(u))
716		{
717			printf("#define LDBL_LLONG_MAX		%llu.0L\n", w);
718			printf("#define LDBL_INTMAX_MAX		LDBL_LLONG_MAX\n");
719		}
720		else
721		{
722			printf("#define LDBL_LLONG_MAX		LDBL_LONG_MAX\n");
723			printf("#define LDBL_INTMAX_MAX		LDBL_LONG_MAX\n");
724		}
725		u++;
726		w++;
727		printf("#define LDBL_LONG_MIN		(-%lu.0L)\n", u);
728		if (sizeof(w) > sizeof(u))
729		{
730			printf("#define LDBL_LLONG_MIN		(-%llu.0L)\n", w);
731			printf("#define LDBL_INTMAX_MIN		LDBL_LLONG_MIN\n");
732		}
733		else
734		{
735			printf("#define LDBL_LLONG_MIN		LDBL_LONG_MIN\n");
736			printf("#define LDBL_INTMAX_MIN		LDBL_LONG_MIN\n");
737		}
738	#ifdef LDBL_DIG
739		s = LDBL_DIG;
740	#else
741		l = pl = 1.0L;
742		s = -1;
743		do
744		{
745			s++;
746			l *= 10.0L;
747		} while (l != (l + pl));
748	#endif
749	#if defined(LDBL_MIN) && defined(LDBL_MIN_EXP)
750		i = LDBL_MIN_EXP;
751		ml = LDBL_MIN;
752	#else
753		i = 3;
754		l = pl = 1.0L;
755		do
756		{
757			i--;
758			ml = pl;
759			pl = l;
760			l /= 2.0L;
761		} while (l < pl);
762	#ifdef LDBL_MIN_EXP
763		i = LDBL_MIN_EXP;
764	#endif
765	#ifdef LDBL_MIN
766		ml = LDBL_MIN;
767	#endif
768	#endif
769	#ifndef LDBL_DIG
770		printf("#ifndef LDBL_DIG\n");
771		printf("#define LDBL_DIG		%d\n", s);
772		printf("#endif\n");
773	#endif
774	#ifndef LDBL_MIN
775		printf("#ifndef LDBL_MIN\n");
776		printf("#define LDBL_MIN		%.*LE%s\n", s + 1, ml, ls);
777		printf("#endif\n");
778	#endif
779	#ifndef LDBL_MIN_EXP
780		printf("#ifndef LDBL_MIN_EXP\n");
781		printf("#define LDBL_MIN_EXP		(%d)\n", i);
782		printf("#endif\n");
783	#endif
784
785	#if defined(LDBL_MAX) && defined(LDBL_MAX_EXP)
786		i = LDBL_MAX_EXP;
787		l = LDBL_MAX;
788	#else
789		i = -1;
790		l = pl = 1.0L;
791		do
792		{
793			i++;
794			ml = pl;
795			pl = l;
796			l *= 2.0L;
797		} while (l > pl);
798		l = 1.0L;
799		do
800		{
801			l *= 2.0L;
802		} while (ml == (ml + l));
803		l = (ml - l) * 2.0L + l;
804	#ifdef LDBL_MAX_EXP
805		i = LDBL_MAX_EXP;
806	#endif
807	#ifdef LDBL_MAX
808		l = LDBL_MAX;
809	#endif
810	#endif
811	#ifndef LDBL_MAX
812		printf("#ifndef LDBL_MAX\n");
813		printf("#define LDBL_MAX		%.*LE%s\n", s + 1, l, ls);
814		printf("#endif\n");
815	#endif
816	#ifndef LDBL_MAX_EXP
817		printf("#ifndef LDBL_MAX_EXP\n");
818		printf("#define LDBL_MAX_EXP		%d\n", i);
819		printf("#endif\n");
820	#endif
821
822	#ifdef LDBL_MIN_10_EXP
823		i = LDBL_MIN_10_EXP;
824	#else
825		i = 2;
826		l = 1.0L;
827		do
828		{
829			i--;
830			pl = l;
831			l /= 10.0L;
832		} while (l < pl);
833	#endif
834	#ifndef LDBL_MIN_10_EXP
835		printf("#ifndef LDBL_MIN_10_EXP\n");
836		printf("#define LDBL_MIN_10_EXP		(%d)\n", i);
837		printf("#endif\n");
838	#endif
839
840	#ifdef LDBL_MAX_10_EXP
841		i = LDBL_MAX_10_EXP;
842	#else
843		i = -2;
844		l = 1.0L;
845		do
846		{
847			i++;
848			pl = l;
849			l *= 10.0L;
850		} while (l > pl);
851	#endif
852	#ifndef LDBL_MAX_10_EXP
853		printf("#ifndef LDBL_MAX_10_EXP\n");
854		printf("#define LDBL_MAX_10_EXP		%d\n", i);
855		printf("#endif\n");
856	#endif
857		fp = "LDBL";
858	#else
859		fp = "DBL";
860	#endif
861
862	printf("\n");
863	printf("#define FLTMAX_UINTMAX_MAX	%s_UINTMAX_MAX\n", fp);
864	printf("#define FLTMAX_INTMAX_MAX	%s_INTMAX_MAX\n", fp);
865	printf("#define FLTMAX_INTMAX_MIN	%s_INTMAX_MIN\n", fp);
866
867	#ifdef SIGFPE
868		if (!caught)
869		{
870	#if !__MVS__
871			f = xf;
872			f *= 2;
873			if (!f)
874	#endif
875				caught = 1;
876		}
877		if (caught)
878			printf("\n#define _ast_fltsig		%d\n", SIGFPE);
879	#endif
880
881		printf("\n");
882	#if !_lib_frexp || _npt_frexp
883		printf("extern double		frexp(double, int*);\n");
884	#endif
885	#if !_lib_frexpl || _npt_frexpl
886		printf("extern _ast_fltmax_t	frexpl(_ast_fltmax_t, int*);\n");
887	#endif
888	#if !_lib_ldexp || _npt_ldexp
889		printf("extern double		ldexp(double, int);\n");
890	#endif
891	#if !_lib_ldexpl || _npt_ldexpl
892		printf("extern _ast_fltmax_t	ldexpl(_ast_fltmax_t, int);\n");
893	#endif
894
895		return 0;
896	}
897}end
898
899tst	- note{ double exponent bitfoolery }end output{
900	#include "FEATURE/common"
901	#include <stdio.h>
902	typedef union _dbl_exp_u
903	{
904		unsigned _ast_int4_t	e[sizeof(double) / 4];
905		double			f;
906	} _ast_dbl_exp_t;
907	int
908	main()
909	{
910		int			i;
911		int			j;
912		unsigned _ast_int4_t	e;
913		_ast_dbl_exp_t		a;
914		_ast_dbl_exp_t		b;
915		a.f = 1;
916		b.f = 2;
917		for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
918			if (e = a.e[i] ^ b.e[i])
919			{
920				for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
921					if (a.e[j] ^ b.e[j])
922						return 0;
923				printf("typedef union _ast_dbl_exp_u\n{\n\tuint32_t\t\te[sizeof(double)/4];\n\tdouble\t\t\tf;\n} _ast_dbl_exp_t;\n\n");
924				printf("#define _ast_dbl_exp_index	%d\n", i);
925				for (i = 0; !(e & 1); e >>= 1, i++);
926				printf("#define _ast_dbl_exp_shift	%d\n\n", i);
927				return 0;
928			}
929		return 0;
930	}
931}end
932
933tst	- note{ long double exponent bitfoolery }end output{
934	#include "FEATURE/common"
935	#include <stdio.h>
936	typedef union _ast_fltmax_exp_u
937	{
938		unsigned _ast_int4_t	e[sizeof(_ast_fltmax_t) / 4];
939		_ast_fltmax_t		f;
940	} _ast_fltmax_exp_t;
941	int
942	main()
943	{
944		int			i;
945		int			j;
946		unsigned _ast_int4_t	e;
947		_ast_fltmax_exp_t	a;
948		_ast_fltmax_exp_t	b;
949		a.f = 1;
950		b.f = 2;
951		for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
952			if (e = a.e[i] ^ b.e[i])
953			{
954				for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
955					if (a.e[j] ^ b.e[j])
956						return 0;
957				printf("typedef union _fltmax_exp_u\n{\n\tuint32_t\t\te[sizeof(_ast_fltmax_t)/4];\n\t_ast_fltmax_t\t\tf;\n} _ast_fltmax_exp_t;\n\n");
958				printf("#define _ast_fltmax_exp_index\t%d\n", i);
959				for (i = 0; !(e & 1); e >>= 1, i++);
960				printf("#define _ast_fltmax_exp_shift\t%d\n\n", i);
961				return 0;
962			}
963		return 0;
964	}
965}end
966
967tst	- -DN=1 - -DN=2 note{ _ast_fltmax_t maximum integral type }end output{
968	#include <stdio.h>
969	int
970	main()
971	{
972	#if N == 1
973		unsigned long long	m;
974		long double		f = 123.456;
975
976		m = f;
977		if (!m || f == m)
978			return 1;
979		printf("#define _ast_flt_unsigned_max_t	unsigned long long\n");
980	#else
981		printf("#define _ast_flt_unsigned_max_t	unsigned long\n");
982	#endif
983		return 0;
984	}
985}end
986
987tst	- -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 note{ INF and NAN memory representations }end output{
988	#if MAC
989	#define _AIX_COMPATIBILITY	1
990	#define _FP_MODE_VARIABLE	1
991	#endif
992	#include "FEATURE/common"
993	#include <stdio.h>
994	#include <sys/types.h>
995	#include <signal.h>
996	#include <strings.h>
997	#if _hdr_float
998	#include <float.h>
999	#endif
1000	#if _hdr_limits
1001	#include <limits.h>
1002	#endif
1003	#if _hdr_math
1004	#include <math.h>
1005	#endif
1006	#if _hdr_values
1007	#include <values.h>
1008	#endif
1009	#if STRTO && _hdr_stdlib
1010	#include <stdlib.h>
1011	#endif
1012	#if !defined(FLT_MAX) && defined(MAXFLOAT)
1013	#define FLT_MAX		MAXFLOAT
1014	#endif
1015	#if !defined(DBL_MAX) && defined(MAXDOUBLE)
1016	#define DBL_MAX		MAXDOUBLE
1017	#endif
1018	#if _ast_fltmax_double
1019	#undef	LDBL_MAX
1020	#endif
1021	static void
1022	#if _STD_
1023	list(const char* typ, const char* var, void* val, int siz)
1024	#else
1025	list(typ, var, val, siz)
1026	char* typ;
1027	char* var;
1028	void* val;
1029	int siz;
1030	#endif
1031	{
1032		register unsigned char*	u = (unsigned char*)val;
1033		register unsigned char*	e = u + siz;
1034
1035		printf("#define _ast_%s_%s_init\t0x%02x", typ, var, *u);
1036		while (++u < e)
1037			printf(",0x%02x", *u);
1038		printf("\n");
1039	}
1040	int
1041	main()
1042	{
1043	#if SCAN || STRTO
1044	#undef	NAN
1045	#define NAN	"NaN"
1046	#undef	INF
1047	#define INF	"INF"
1048	{
1049		float	f;
1050
1051	#if SCAN
1052		if (sscanf(NAN, "%g", &f) != 1)
1053			return 1;
1054	#else
1055		f = atof(NAN);
1056	#endif
1057		list("flt", "nan", &f, sizeof(f));
1058	#if SCAN
1059		if (sscanf(INF, "%g", &f) != 1)
1060			return 1;
1061	#else
1062		f = atof(INF);
1063	#endif
1064		list("flt", "inf", &f, sizeof(f));
1065	}
1066	{
1067		double	f;
1068	#if STRTO
1069		char*	e;
1070	#endif
1071
1072	#if SCAN
1073		if (sscanf(NAN, "%lg", &f) != 1)
1074			return 1;
1075	#else
1076		f = strtod(NAN, &e);
1077		if (*e)
1078			return 1;
1079	#endif
1080		list("dbl", "nan", &f, sizeof(f));
1081	#if SCAN
1082		if (sscanf(INF, "%lg", &f) != 1)
1083			return 1;
1084	#else
1085		f = strtod(INF, &e);
1086		if (*e)
1087			return 1;
1088	#endif
1089		list("dbl", "inf", &f, sizeof(f));
1090	}
1091	#ifdef LDBL_MAX
1092	{
1093		long double	f;
1094	#if STRTO
1095		char*	e;
1096	#endif
1097
1098	bzero(&f, sizeof (f));
1099	#if SCAN
1100		if (sscanf(NAN, "%Lg", &f) != 1)
1101			return 1;
1102	#else
1103		f = strtold(NAN, &e);
1104		if (*e)
1105			return 1;
1106	#endif
1107		list("ldbl", "nan", &f, sizeof(f));
1108	bzero(&f, sizeof (f));
1109	#if SCAN
1110		if (sscanf(INF, "%Lg", &f) != 1)
1111			return 1;
1112	#else
1113		f = strtold(INF, &e);
1114		if (*e)
1115			return 1;
1116	#endif
1117		list("ldbl", "inf", &f, sizeof(f));
1118	}
1119	#endif
1120	#else
1121	#ifdef SIGFPE
1122		signal(SIGFPE, SIG_IGN);
1123	#endif
1124	#ifdef FLT_MAX
1125		{
1126			float	f = FLT_MAX;
1127	#if DIV
1128			float	z = 0;
1129
1130			f = 0.0 / z;
1131			if (!f)
1132				return 1;
1133			list("flt", "nan", &f, sizeof(f));
1134			f = 1.0 / z;
1135			list("flt", "inf", &f, sizeof(f));
1136	#else
1137	#if ADD
1138			f += f;
1139	#endif
1140	#if EXP
1141			f = exp(f);
1142	#endif
1143	#if MPY
1144			f *= 2;
1145	#endif
1146	#if MAC
1147			f = FLT_QNAN;
1148	#endif
1149			list("flt", "nan", &f, sizeof(f));
1150	#if MAC
1151			f = FLT_INFINITY;
1152	#endif
1153			list("flt", "inf", &f, sizeof(f));
1154	#endif
1155		}
1156	#endif
1157	#ifdef DBL_MAX
1158		{
1159			double	f = DBL_MAX;
1160	#if DIV
1161			double	z = 0;
1162
1163			f = 0.0 / z;
1164			if (!f)
1165				return 1;
1166			list("dbl", "nan", &f, sizeof(f));
1167			f = 1.0 / z;
1168			list("dbl", "inf", &f, sizeof(f));
1169	#else
1170	#if ADD
1171			f += f;
1172	#endif
1173	#if EXP
1174			f = exp(f);
1175	#endif
1176	#if MPY
1177			f *= 2;
1178	#endif
1179	#if MAC
1180			f = DBL_QNAN;
1181	#endif
1182			list("dbl", "nan", &f, sizeof(f));
1183	#if MAC
1184			f = DBL_INFINITY;
1185	#endif
1186			list("dbl", "inf", &f, sizeof(f));
1187	#endif
1188		}
1189	#endif
1190	#ifdef LDBL_MAX
1191		{
1192			long double	f = LDBL_MAX;
1193	#if DIV
1194			long double	z = 0;
1195
1196			f = 0.0 / z;
1197			if (!f)
1198				return 1;
1199			list("ldbl", "nan", &f, sizeof(f));
1200			f = 1.0 / z;
1201			list("ldbl", "inf", &f, sizeof(f));
1202	#else
1203	#if ADD
1204			f += f;
1205	#endif
1206	#if EXP
1207			f = exp(f);
1208	#endif
1209	#if MPY
1210			f *= 2;
1211	#endif
1212	#if MAC
1213			f = LDBL_QNAN;
1214	#endif
1215			list("ldbl", "nan", &f, sizeof(f));
1216	#if MAC
1217			f = LDBL_INFINITY;
1218	#endif
1219			list("ldbl", "inf", &f, sizeof(f));
1220	#endif
1221		}
1222	#endif
1223	#endif
1224		return 0;
1225	}
1226}end
1227