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