set	prototyped
hdr	float,limits,math,values
lib	frexp,frexpl,ldexp,ldexpl -lm

tst	ast_no_um2fm note{ no unsigned intmax => floatmax cast }end nolink{
	#include "FEATURE/common"
	main()
	{
		_ast_fltmax_t		f = 0;
		unsigned _ast_intmax_t	i = 0;
		f = i;
		i = f;
		return f == i;
	}
}end

tst	ast_mpy_overflow_fpe note{ fpe on mpy overflow }end noexecute{
	main()
	{
		float	f;
		float	p;
		int	i;

		i = 0;
		p = f = 1.0;
		do
		{
			p = f;
			f *= 2.0;
		} while (f != p && ++i < 1024);
		return 0;
	}
}end

tst	ast_div_underflow_fpe note{ fpe on div underflow }end noexecute{
	main()
	{
		float	f;
		float	p;
		int	i;

		i = 0;
		p = f = 1.0;
		do
		{
			p = f;
			f /= 2.0;
		} while (f != p && ++i < 1024);
		return 0;
	}
}end

macro{
	#if _hdr_float
	#include <float.h>
	#endif
	#if _hdr_limits
	#include <limits.h>
	#endif
	#if _hdr_math
	#include <math.h>
	#endif
	#if _hdr_values
	#include <values.h>
	#endif

	#if !defined(FLT_MIN_EXP) && defined(FMINEXP)
	#define FLT_MIN_EXP	FMINEXP
	#endif
	#if !defined(FLT_MIN) && defined(MINFLOAT)
	#define FLT_MIN		MINFLOAT
	#endif
	#if !defined(FLT_MAX_EXP) && defined(FMAXEXP)
	#define FLT_MAX_EXP	FMAXEXP
	#endif
	#if !defined(FLT_MAX) && defined(MAXFLOAT)
	#define FLT_MAX		MAXFLOAT
	#endif

	#if !defined(DBL_MIN_EXP) && defined(DMINEXP)
	#define DBL_MIN_EXP	DMINEXP
	#endif
	#if !defined(DBL_MIN) && defined(MINDOUBLE)
	#define DBL_MIN		MINDOUBLE
	#endif
	#if !defined(DBL_MAX_EXP) && defined(DMAXEXP)
	#define DBL_MAX_EXP	DMAXEXP
	#endif
	#if !defined(DBL_MAX) && defined(MAXDOUBLE)
	#define DBL_MAX		MAXDOUBLE
	#endif

	<<"#include <ast_common.h>">>
	#if _hdr_float
	<<"#include <float.h>">>
	#endif
	#if _hdr_math
	<<"#include <math.h>">>
	#endif
	#ifdef FLT_DIG
	<<"#ifndef FLT_DIG">>
	<<"#define FLT_DIG">>		FLT_DIG
	<<"#endif">>
	#endif
	#ifdef FLT_MAX
	<<"#ifndef FLT_MAX">>
	<<"#define FLT_MAX">>		FLT_MAX
	<<"#endif">>
	#endif
	#ifdef FLT_MAX_10_EXP
	<<"#ifndef FLT_MAX_10_EXP">>
	<<"#define FLT_MAX_10_EXP">>	FLT_MAX_10_EXP
	<<"#endif">>
	#endif
	#ifdef FLT_MAX_EXP
	<<"#ifndef FLT_MAX_EXP">>
	<<"#define FLT_MAX_EXP">>	FLT_MAX_EXP
	<<"#endif">>
	#endif
	#ifdef FLT_MIN
	<<"#ifndef FLT_MIN">>
	<<"#define FLT_MIN">>		FLT_MIN
	<<"#endif">>
	#endif
	#ifdef FLT_MIN_10_EXP
	<<"#ifndef FLT_MIN_10_EXP">>
	<<"#define FLT_MIN_10_EXP">>	FLT_MIN_10_EXP
	<<"#endif">>
	#endif
	#ifdef FLT_MIN_EXP
	<<"#ifndef FLT_MIN_EXP">>
	<<"#define FLT_MIN_EXP">>	FLT_MIN_EXP
	<<"#endif">>
	#endif

	#ifdef DBL_DIG
	<<"#ifndef DBL_DIG">>
	<<"#define DBL_DIG">>		DBL_DIG
	<<"#endif">>
	#endif
	#ifdef DBL_MAX
	<<"#ifndef DBL_MAX">>
	<<"#define DBL_MAX">>		DBL_MAX
	<<"#endif">>
	#endif
	#ifdef DBL_MAX_10_EXP
	<<"#ifndef DBL_MAX_10_EXP">>
	<<"#define DBL_MAX_10_EXP">>	DBL_MAX_10_EXP
	<<"#endif">>
	#endif
	#ifdef DBL_MAX_EXP
	<<"#ifndef DBL_MAX_EXP">>
	<<"#define DBL_MAX_EXP">>	DBL_MAX_EXP
	<<"#endif">>
	#endif
	#ifdef DBL_MIN
	<<"#ifndef DBL_MIN">>
	<<"#define DBL_MIN">>		DBL_MIN
	<<"#endif">>
	#endif
	#ifdef DBL_MIN_10_EXP
	<<"#ifndef DBL_MIN_10_EXP">>
	<<"#define DBL_MIN_10_EXP">>	DBL_MIN_10_EXP
	<<"#endif">>
	#endif
	#ifdef DBL_MIN_EXP
	<<"#ifndef DBL_MIN_EXP">>
	<<"#define DBL_MIN_EXP">>	DBL_MIN_EXP
	<<"#endif">>
	#endif

	#ifdef LDBL_DIG
	<<"#ifndef LDBL_DIG">>
	<<"#define LDBL_DIG">>		LDBL_DIG
	<<"#endif">>
	#endif
	#ifdef LDBL_MAX
	<<"#ifndef LDBL_MAX">>
	<<"#define LDBL_MAX">>		LDBL_MAX
	<<"#endif">>
	#endif
	#ifdef LDBL_MAX_10_EXP
	<<"#ifndef LDBL_MAX_10_EXP">>
	<<"#define LDBL_MAX_10_EXP">>	LDBL_MAX_10_EXP
	<<"#endif">>
	#endif
	#ifdef LDBL_MAX_EXP
	<<"#ifndef LDBL_MAX_EXP">>
	<<"#define LDBL_MAX_EXP">>	LDBL_MAX_EXP
	<<"#endif">>
	#endif
	#ifdef LDBL_MIN
	<<"#ifndef LDBL_MIN">>
	<<"#define LDBL_MIN">>		LDBL_MIN
	<<"#endif">>
	#endif
	#ifdef LDBL_MIN_10_EXP
	<<"#ifndef LDBL_MIN_10_EXP">>
	<<"#define LDBL_MIN_10_EXP">>	LDBL_MIN_10_EXP
	<<"#endif">>
	#endif
	#ifdef LDBL_MIN_EXP
	<<"#ifndef LDBL_MIN_EXP">>
	<<"#define LDBL_MIN_EXP">>	LDBL_MIN_EXP
	<<"#endif">>
	#endif
}end

tst	- note{ missing floating point limits }end output{
	#include "FEATURE/common"
	#if _hdr_float
	#include <float.h>
	#endif
	#if _hdr_limits
	#include <limits.h>
	#endif
	#if _hdr_math
	#include <math.h>
	#endif
	#if _hdr_values
	#include <values.h>
	#endif
	#include <signal.h>
	#ifdef SIGFPE
	static int caught = 0;
	#if _STD_
	static void catch(int sig)
	#else
	static void catch(sig) int sig;
	#endif
	{
		signal(sig, SIG_IGN);
		caught++;
	}
	#endif
	main()
	{
		register int		i;
		register int		s;
		float			f;
		float			pf;
		float			mf;
		float			xf;
		double			d;
		double			pd;
		double			md;
		char*			fp;
	#if _ast_fltmax_double
		char*			fs = "";
		char*			ds = "";
	#else
		_ast_fltmax_t		l;
		_ast_fltmax_t		pl;
		_ast_fltmax_t		ml;
		char*			fs = "F";
		char*			ds = "";
		char*			ls = "L";
	#endif
		unsigned long		u;
		unsigned _ast_intmax_t	w;
		unsigned _ast_intmax_t	pw;
		unsigned _ast_intmax_t	x;
		unsigned short		us;
		unsigned int		ui;
		unsigned long		ul;
		unsigned _ast_intmax_t	uq;
	
	#ifdef SIGFPE
		signal(SIGFPE, catch);
	#endif
		printf("\n");
		printf("\n");
		us = 0;
		us = ~us;
		i = 0;
		while (us /= 10)
			i++;
		printf("#define USHRT_DIG		%d\n", i);
		ui = 0;
		ui = ~ui;
		i = 0;
		while (ui /= 10)
			i++;
		printf("#define UINT_DIG		%d\n", i);
		ul = 0;
		ul = ~ul;
		i = 0;
		while (ul /= 10)
			i++;
		printf("#define ULONG_DIG		%d\n", i);
		if (sizeof(uq) > sizeof(ul))
		{
			uq = 0;
			uq = ~uq;
			i = 0;
			while (uq /= 10)
				i++;
			printf("#define ULONGLONG_DIG		%d\n", i);
			printf("#define UINTMAX_DIG		ULONGLONG_DIG\n");
		}
		else
			printf("#define UINTMAX_DIG		ULONG_DIG\n");
		printf("\n");
		w = 1;
		do
		{
			pw = w;
			w *= 2;
			f = (_ast_intmax_t)w;
			x = (_ast_intmax_t)f;
		} while (w > pw && w == x);
		w = (pw - 1) + pw;
		u = ~0;
		if (u > w)
			u = w;
		printf("#define FLT_ULONG_MAX		%lu.0F\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define FLT_ULONGLONG_MAX	%llu.0F\n", w);
			printf("#define FLT_UINTMAX_MAX		FLT_ULONGLONG_MAX\n");
		}
		else
		{
			printf("#define FLT_ULONGLONG_MAX	FLT_ULONG_MAX\n");
			printf("#define FLT_UINTMAX_MAX		FLT_ULONG_MAX\n");
		}
		u /= 2;
		w /= 2;
		printf("#define FLT_LONG_MAX		%lu.0F\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define FLT_LONGLONG_MAX	%llu.0F\n", w);
			printf("#define FLT_INTMAX_MAX		FLT_LONGLONG_MAX\n");
		}
		else
		{
			printf("#define FLT_LONGLONG_MAX	FLT_LONG_MAX\n");
			printf("#define FLT_INTMAX_MAX		FLT_LONG_MAX\n");
		}
		u++;
		w++;
		printf("#define FLT_LONG_MIN		(-%lu.0F)\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define FLT_LONGLONG_MIN	(-%llu.0F)\n", w);
			printf("#define FLT_INTMAX_MIN		FLT_LONGLONG_MIN\n");
		}
		else
		{
			printf("#define FLT_LONGLONG_MIN	FLT_LONG_MIN\n");
			printf("#define FLT_INTMAX_MIN		FLT_LONG_MIN\n");
		}
	#ifdef FLT_DIG
		s = FLT_DIG;
	#else
		f = pf = 1.0;
		s = -1;
		do
		{
			s++;
			f *= 10.0;
		} while (f != (f + pf));
	#endif
	#if defined(FLT_MIN) && defined(FLT_MIN_EXP)
		i = FLT_MIN_EXP;
		mf = FLT_MIN;
	#else
		i = 3;
		f = pf = 1.0;
		do
		{
			i--;
			mf = pf;
			pf = f;
			f /= 2.0;
		} while (f < pf);
	#ifdef FLT_MIN_EXP
		i = FLT_MIN_EXP;
	#endif
	#ifdef FLT_MIN
		mf = FLT_MIN;
	#endif
	#endif
	#ifndef FLT_DIG
		printf("#ifndef FLT_DIG\n");
		printf("#define FLT_DIG			%d\n", s);
		printf("#endif\n");
	#endif
	#ifndef FLT_MIN
		printf("#ifndef FLT_MIN\n");
		printf("#define FLT_MIN			%.*E%s\n", s + 1, mf, fs);
		printf("#endif\n");
	#endif
	#ifndef FLT_MIN_EXP
		printf("#ifndef FLT_MIN_EXP\n");
		printf("#define FLT_MIN_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#if defined(FLT_MAX) && defined(FLT_MAX_EXP)
		i = FLT_MAX_EXP;
		f = FLT_MAX;
	#else
		i = -1;
		f = pf = 1.0;
		do
		{
			i++;
			mf = pf;
			pf = f;
			f *= 2.0;
		} while (f > pf);
	#ifdef FLT_MAX_EXP
		i = FLT_MAX_EXP;
	#endif
	#ifdef FLT_MAX
		f = FLT_MAX;
	#endif
	#endif
	#ifdef FLT_MAX_EXP
		i = FLT_MAX_EXP;
	#else
		f = 1;
		do
		{
			f *= 2.0;
		} while (mf == (mf + f));
		f = (mf - f) * 2.0 + f;
	#endif
		xf = f;
	#ifndef FLT_MAX
		printf("#ifndef FLT_MAX\n");
		printf("#define FLT_MAX			%.*E%s\n", s + 1, f, fs);
		printf("#endif\n");
	#endif
	#ifndef FLT_MAX_EXP
		printf("#ifndef FLT_MAX_EXP\n");
		printf("#define FLT_MAX_EXP		%d\n", i);
		printf("#endif\n");
	#endif

	#ifdef FLT_MIN_10_EXP
		i = FLT_MIN_10_EXP;
	#else
		i = 2;
		f = 1.0;
		do
		{
			i--;
			pf = f;
			f /= 10.0;
		} while (f < pf);
	#endif
	#ifndef FLT_MIN_10_EXP
		printf("#ifndef FLT_MIN_10_EXP\n");
		printf("#define FLT_MIN_10_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#ifdef FLT_MAX_10_EXP
		i = FLT_MAX_10_EXP;
	#else
		i = -2;
		f = 1.0;
		do
		{
			i++;
			pf = f;
			f *= 10.0;
		} while (f > pf);
	#endif
	#ifndef FLT_MAX_10_EXP
		printf("#ifndef FLT_MAX_10_EXP\n");
		printf("#define FLT_MAX_10_EXP		%d\n", i);
		printf("#endif\n");
	#endif

		printf("\n");
		w = 1;
		do
		{
			pw = w;
			w *= 2;
			d = (_ast_intmax_t)w;
			x = (_ast_intmax_t)d;
		} while (w > pw && w == x);
		w = (pw - 1) + pw;
		u = ~0;
		if (u > w)
			u = w;
		printf("#define DBL_ULONG_MAX		%lu.0\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define DBL_ULONGLONG_MAX	%llu.0\n", w);
			printf("#define DBL_UINTMAX_MAX		DBL_ULONGLONG_MAX\n");
		}
		else
		{
			printf("#define DBL_ULONGLONG_MAX	DBL_ULONG_MAX\n");
			printf("#define DBL_UINTMAX_MAX		DBL_ULONG_MAX\n");
		}
		u /= 2;
		w /= 2;
		printf("#define DBL_LONG_MAX		%lu.0\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define DBL_LONGLONG_MAX	%llu.0\n", w);
			printf("#define DBL_INTMAX_MAX		DBL_LONGLONG_MAX\n");
		}
		else
		{
			printf("#define DBL_LONGLONG_MAX	DBL_LONG_MAX\n");
			printf("#define DBL_INTMAX_MAX		DBL_LONG_MAX\n");
		}
		u++;
		w++;
		printf("#define DBL_LONG_MIN		(-%lu.0)\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define DBL_LONGLONG_MIN	(-%llu.0)\n", w);
			printf("#define DBL_INTMAX_MIN		DBL_LONGLONG_MIN\n");
		}
		else
		{
			printf("#define DBL_LONGLONG_MIN	DBL_LONG_MIN\n");
			printf("#define DBL_INTMAX_MIN		DBL_LONG_MIN\n");
		}
	#ifdef DBL_DIG
		s = DBL_DIG;
	#else
		d = pd = 1.0;
		s = -1;
		do
		{
			s++;
			d *= 10.0;
		} while (d != (d + pd));
	#endif
	#if defined(DBL_MIN) && defined(DBL_MIN_EXP)
		i = DBL_MIN_EXP;
		md = DBL_MIN;
	#else
		i = 3;
		d = pd = 1.0;
		do
		{
			i--;
			md = pd;
			pd = d;
			d /= 2.0;
		} while (d < pd);
	#ifdef DBL_MIN_EXP
		i = DBL_MIN_EXP;
	#endif
	#ifdef DBL_MIN
		md = DBL_MIN;
	#endif
	#endif
	#ifndef DBL_DIG
		printf("#ifndef DBL_DIG\n");
		printf("#define DBL_DIG			%d\n", s);
		printf("#endif\n");
	#endif
	#ifndef DBL_MIN
		printf("#ifndef DBL_MIN\n");
		printf("#define DBL_MIN			%.*E%s\n", s + 1, md, ds);
		printf("#endif\n");
	#endif
	#ifndef DBL_MIN_EXP
		printf("#ifndef DBL_MIN_EXP\n");
		printf("#define DBL_MIN_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#if defined(DBL_MAX) && defined(DBL_MAX_EXP)
		i = DBL_MAX_EXP;
		d = DBL_MAX;
	#else
		i = -1;
		d = pd = 1.0;
		do
		{
			i++;
			md = pd;
			pd = d;
			d *= 2.0;
		} while (d > pd);
		d = 1.0;
		do
		{
			d *= 2.0;
		} while (md == (md + d));
		d = (md - d) * 2.0 + d;
	#ifdef DBL_MAX_EXP
		i = DBL_MAX_EXP;
	#endif
	#ifdef DBL_MAX
		d = DBL_MAX;
	#endif
	#endif
	#ifndef DBL_MAX
		printf("#ifndef DBL_MAX\n");
		printf("#define DBL_MAX			%.*E%s\n", s + 1, d, ds);
		printf("#endif\n");
	#endif
	#ifndef DBL_MAX_EXP
		printf("#ifndef DBL_MAX_EXP\n");
		printf("#define DBL_MAX_EXP		%d\n", i);
		printf("#endif\n");
	#endif

	#ifdef DBL_MIN_10_EXP
		i = DBL_MIN_10_EXP;
	#else
		i = 2;
		d = 1.0;
		do
		{
			i--;
			pd = d;
			d /= 10.0;
		} while (d < pd);
	#endif
	#ifndef DBL_MIN_10_EXP
		printf("#ifndef DBL_MIN_10_EXP\n");
		printf("#define DBL_MIN_10_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#ifdef DBL_MAX_10_EXP
		i = DBL_MAX_10_EXP;
	#else
		i = -2;
		d = 1.0;
		do
		{
			i++;
			pd = d;
			d *= 10.0;
		} while (d > pd);
	#endif
	#ifndef DBL_MAX_10_EXP
		printf("#ifndef DBL_MAX_10_EXP\n");
		printf("#define DBL_MAX_10_EXP		%d\n", i);
		printf("#endif\n");
	#endif

	#if !_ast_fltmax_double
		printf("\n");
		w = 1;
		do
		{
			pw = w;
			w *= 2;
			l = (_ast_intmax_t)w;
			x = (_ast_intmax_t)l;
		} while (w > pw && w == x);
		w = (pw - 1) + pw;
		u = ~0;
		if (u > w)
			u = w;
		printf("#define LDBL_ULONG_MAX		%lu.0L\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define LDBL_ULONGLONG_MAX	%llu.0L\n", w);
			printf("#define LDBL_UINTMAX_MAX	LDBL_ULONGLONG_MAX\n");
		}
		else
		{
			printf("#define LDBL_ULONGLONG_MAX	LDBL_ULONG_MAX\n");
			printf("#define LDBL_UINTMAX_MAX	LDBL_ULONG_MAX\n");
		}
		u /= 2;
		w /= 2;
		printf("#define LDBL_LONG_MAX		%lu.0L\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define LDBL_LONGLONG_MAX	%llu.0L\n", w);
			printf("#define LDBL_INTMAX_MAX		LDBL_LONGLONG_MAX\n");
		}
		else
		{
			printf("#define LDBL_LONGLONG_MAX	LDBL_LONG_MAX\n");
			printf("#define LDBL_INTMAX_MAX		LDBL_LONG_MAX\n");
		}
		u++;
		w++;
		printf("#define LDBL_LONG_MIN		(-%lu.0L)\n", u);
		if (sizeof(w) > sizeof(u))
		{
			printf("#define LDBL_LONGLONG_MIN	(-%llu.0L)\n", w);
			printf("#define LDBL_INTMAX_MIN		LDBL_LONGLONG_MIN\n");
		}
		else
		{
			printf("#define LDBL_LONGLONG_MIN	LDBL_LONG_MIN\n");
			printf("#define LDBL_INTMAX_MIN		LDBL_LONG_MIN\n");
		}
	#ifdef LDBL_DIG
		s = LDBL_DIG;
	#else
		l = pl = 1.0L;
		s = -1;
		do
		{
			s++;
			l *= 10.0L;
		} while (l != (l + pl));
	#endif
	#if defined(LDBL_MIN) && defined(LDBL_MIN_EXP)
		i = LDBL_MIN_EXP;
		ml = LDBL_MIN;
	#else
		i = 3;
		l = pl = 1.0L;
		do
		{
			i--;
			ml = pl;
			pl = l;
			l /= 2.0L;
		} while (l < pl);
	#ifdef LDBL_MIN_EXP
		i = LDBL_MIN_EXP;
	#endif
	#ifdef LDBL_MIN
		ml = LDBL_MIN;
	#endif
	#endif
	#ifndef LDBL_DIG
		printf("#ifndef LDBL_DIG\n");
		printf("#define LDBL_DIG		%d\n", s);
		printf("#endif\n");
	#endif
	#ifndef LDBL_MIN
		printf("#ifndef LDBL_MIN\n");
		printf("#define LDBL_MIN		%.*LE%s\n", s + 1, ml, ls);
		printf("#endif\n");
	#endif
	#ifndef LDBL_MIN_EXP
		printf("#ifndef LDBL_MIN_EXP\n");
		printf("#define LDBL_MIN_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#if defined(LDBL_MAX) && defined(LDBL_MAX_EXP)
		i = LDBL_MAX_EXP;
		l = LDBL_MAX;
	#else
		i = -1;
		l = pl = 1.0L;
		do
		{
			i++;
			ml = pl;
			pl = l;
			l *= 2.0L;
		} while (l > pl);
		l = 1.0L;
		do
		{
			l *= 2.0L;
		} while (ml == (ml + l));
		l = (ml - l) * 2.0L + l;
	#ifdef LDBL_MAX_EXP
		i = LDBL_MAX_EXP;
	#endif
	#ifdef LDBL_MAX
		l = LDBL_MAX;
	#endif
	#endif
	#ifndef LDBL_MAX
		printf("#ifndef LDBL_MAX\n");
		printf("#define LDBL_MAX		%.*LE%s\n", s + 1, l, ls);
		printf("#endif\n");
	#endif
	#ifndef LDBL_MAX_EXP
		printf("#ifndef LDBL_MAX_EXP\n");
		printf("#define LDBL_MAX_EXP		%d\n", i);
		printf("#endif\n");
	#endif

	#ifdef LDBL_MIN_10_EXP
		i = LDBL_MIN_10_EXP;
	#else
		i = 2;
		l = 1.0L;
		do
		{
			i--;
			pl = l;
			l /= 10.0L;
		} while (l < pl);
	#endif
	#ifndef LDBL_MIN_10_EXP
		printf("#ifndef LDBL_MIN_10_EXP\n");
		printf("#define LDBL_MIN_10_EXP		(%d)\n", i);
		printf("#endif\n");
	#endif

	#ifdef LDBL_MAX_10_EXP
		i = LDBL_MAX_10_EXP;
	#else
		i = -2;
		l = 1.0L;
		do
		{
			i++;
			pl = l;
			l *= 10.0L;
		} while (l > pl);
	#endif
	#ifndef LDBL_MAX_10_EXP
		printf("#ifndef LDBL_MAX_10_EXP\n");
		printf("#define LDBL_MAX_10_EXP		%d\n", i);
		printf("#endif\n");
	#endif
		fp = "LDBL";
	#else
		fp = "DBL";
	#endif

	printf("\n");
	printf("#define FLTMAX_UINTMAX_MAX	%s_UINTMAX_MAX\n", fp);
	printf("#define FLTMAX_INTMAX_MAX	%s_INTMAX_MAX\n", fp);
	printf("#define FLTMAX_INTMAX_MIN	%s_INTMAX_MIN\n", fp);

	#ifdef SIGFPE
		if (!caught)
		{
			f = xf;
			f *= 2;
			if (!f)
				caught = 1;
		}
		if (caught)
			printf("\n#define _ast_fltsig		%d\n", SIGFPE);
	#endif

		printf("\n");
	#if !_lib_frexp
		printf("extern double		frexp(double, int*);\n");
	#endif
	#if !_lib_frexpl
		printf("extern _ast_fltmax_t	frexpl(_ast_fltmax_t, int*);\n");
	#endif
	#if !_lib_ldexp
		printf("extern double		ldexp(double, int);\n");
	#endif
	#if !_lib_ldexpl
		printf("extern _ast_fltmax_t	ldexpl(_ast_fltmax_t, int);\n");
	#endif

		return 0;
	}
}end

tst	- note{ double exponent bitfoolery }end output{
	#include "FEATURE/common"
	typedef union _dbl_exp_u
	{
		unsigned _ast_int4_t	e[sizeof(double) / 4];
		double			f;
	} _ast_dbl_exp_t;
	main()
	{
		int			i;
		int			j;
		unsigned _ast_int4_t	e;
		_ast_dbl_exp_t		a;
		_ast_dbl_exp_t		b;
		a.f = 1;
		b.f = 2;
		for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
			if (e = a.e[i] ^ b.e[i])
			{
				for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
					if (a.e[j] ^ b.e[j])
						return 0;
				printf("typedef union _ast_dbl_exp_u\n{\n\tunsigned _ast_int4_t\te[sizeof(double)/4];\n\tdouble\t\t\tf;\n} _ast_dbl_exp_t;\n\n");
				printf("#define _ast_dbl_exp_index	%d\n", i);
				for (i = 0; !(e & 1); e >>= 1, i++);
				printf("#define _ast_dbl_exp_shift	%d\n\n", i);
				return 0;
			}
		return 0;
	}
}end

tst	- note{ long double exponent bitfoolery }end output{
	#include "FEATURE/common"
	typedef union _ast_fltmax_exp_u
	{
		unsigned _ast_int4_t	e[sizeof(_ast_fltmax_t) / 4];
		_ast_fltmax_t		f;
	} _ast_fltmax_exp_t;
	main()
	{
		int			i;
		int			j;
		unsigned _ast_int4_t	e;
		_ast_fltmax_exp_t	a;
		_ast_fltmax_exp_t	b;
		a.f = 1;
		b.f = 2;
		for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
			if (e = a.e[i] ^ b.e[i])
			{
				for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
					if (a.e[j] ^ b.e[j])
						return 0;
				printf("typedef union _fltmax_exp_u\n{\n\tunsigned _ast_int4_t\te[sizeof(_ast_fltmax_t)/4];\n\t_ast_fltmax_t\t\tf;\n} _ast_fltmax_exp_t;\n\n");
				printf("#define _ast_fltmax_exp_index\t%d\n", i);
				for (i = 0; !(e & 1); e >>= 1, i++);
				printf("#define _ast_fltmax_exp_shift\t%d\n\n", i);
				return 0;
			}
		return 0;
	}
}end

tst	- -DN=1 - -DN=2 note{ _ast_fltmax_t maximum integral type }end output{
	main()
	{
	#if N == 1
		unsigned long long	m;
		long double		f = 123.456;

		m = f;
		if (!m || f == m)
			return 1;
		printf("#define _ast_flt_unsigned_max_t	unsigned long long\n");
	#else
		printf("#define _ast_flt_unsigned_max_t	unsigned long\n");
	#endif
		return 0;
	}
}end

tst	- -lm -DSCAN=1 - -DEXP=1 - -DADD=1 - -DMPY=1 note{ nan memory representations }end output{
	#include "FEATURE/common"
	#include <sys/types.h>
	#include <signal.h>
	#if _hdr_float
	#include <float.h>
	#endif
	#if _hdr_limits
	#include <limits.h>
	#endif
	#if _hdr_math
	#include <math.h>
	#endif
	#if _hdr_values
	#include <values.h>
	#endif
	#if !defined(FLT_MAX) && defined(MAXFLOAT)
	#define FLT_MAX		MAXFLOAT
	#endif
	#if !defined(DBL_MAX) && defined(MAXDOUBLE)
	#define DBL_MAX		MAXDOUBLE
	#endif
	static void
	#if _STD_
	list(const char* pfx, void* val, int siz)
	#else
	list(pfx, val, siz)
	char* pfx;
	void* val;
	int siz;
	#endif
	{
		register unsigned char*	u = (unsigned char*)val;
		register unsigned char*	e = u + siz;
	
		printf("#define _ast_%s_nan_init\t0x%02x", pfx, *u);
		while (++u < e)
			printf(",0x%02x", *u);
		printf("\n");
	}
	main()
	{
	#if SCAN
	#define STR	"NaNQ"
	{
		float	f;

		if (sscanf(STR, "%g", &f) != 1)
			return 1;
		list("flt", &f, sizeof(f));
	}
	{
		double	f;

		if (sscanf(STR, "%lg", &f) != 1)
			return 1;
		list("dbl", &f, sizeof(f));
	}
	#ifdef LDBL_MAX
	{
		long double	f;

		if (sscanf(STR, "%Lg", &f) != 1)
			return 1;
		list("ldbl", &f, sizeof(f));
	}
	#endif
	#else
	#ifdef SIGFPE
		signal(SIGFPE, SIG_IGN);
	#endif
	#ifdef FLT_MAX
		{
			float	f = FLT_MAX;
	#if ADD
			f += f;
	#endif
	#if EXP
			f = exp(f);
	#endif
	#if MPY
			f *= 2;
	#endif
			list("flt", &f, sizeof(f));
		}
	#endif
	#ifdef DBL_MAX
		{
			double	f = DBL_MAX;
	#if ADD
			f += f;
	#endif
	#if EXP
			f = exp(f);
	#endif
	#if MPY
			f *= 2;
	#endif
			list("dbl", &f, sizeof(f));
		}
	#endif
	#ifdef LDBL_MAX
		{
			long double	f = LDBL_MAX;
	#if ADD
			f += f;
	#endif
	#if EXP
			f = exp(f);
	#endif
	#if MPY
			f *= 2;
	#endif
			list("ldbl", &f, sizeof(f));
		}
	#endif
	#endif
		return 0;
	}
}end
