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