1165743Sdas/****************************************************************
2165743Sdas
3165743SdasThe author of this software is David M. Gay.
4165743Sdas
5165743SdasCopyright (C) 2005 by David M. Gay
6165743SdasAll Rights Reserved
7165743Sdas
8165743SdasPermission to use, copy, modify, and distribute this software and its
9165743Sdasdocumentation for any purpose and without fee is hereby granted,
10165743Sdasprovided that the above copyright notice appear in all copies and that
11165743Sdasboth that the copyright notice and this permission notice and warranty
12165743Sdasdisclaimer appear in supporting documentation, and that the name of
13165743Sdasthe author or any of his current or former employers not be used in
14165743Sdasadvertising or publicity pertaining to distribution of the software
15165743Sdaswithout specific, written prior permission.
16165743Sdas
17165743SdasTHE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18165743SdasINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN
19165743SdasNO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE
20165743SdasLIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
21165743SdasDAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22165743SdasWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23165743SdasARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24165743SdasSOFTWARE.
25165743Sdas
26165743Sdas****************************************************************/
27165743Sdas
28165743Sdas/* Please send bug reports to David M. Gay (dmg at acm dot org,
29165743Sdas * with " at " changed at "@" and " dot " changed to ".").	*/
30165743Sdas
31165743Sdas/* Program to compute quiet NaNs of various precisions (float,	*/
32165743Sdas/* double, and perhaps long double) on the current system,	*/
33165743Sdas/* provided the system uses binary IEEE (P754) arithmetic.	*/
34165743Sdas/* Note that one system's quiet NaN may be a signaling NaN on	*/
35165743Sdas/* another system.  The IEEE arithmetic standards (P754, P854)	*/
36165743Sdas/* do not specify how to distinguish signaling NaNs from quiet	*/
37165743Sdas/* ones, and this detail varies across systems.	 The computed	*/
38165743Sdas/* NaN values are encoded in #defines for values for an		*/
39165743Sdas/* unsigned 32-bit integer type, called Ulong below, and	*/
40165743Sdas/* (for long double) perhaps as unsigned short values.  Once	*/
41165743Sdas/* upon a time, there were PC compilers for Intel CPUs that	*/
42165743Sdas/* had sizeof(long double) = 10.  Are such compilers still	*/
43165743Sdas/* distributed?							*/
44165743Sdas
45165743Sdas#include <stdio.h>
46165743Sdas#include "arith.h"
47165743Sdas
48165743Sdas#ifndef Long
49165743Sdas#define Long long
50165743Sdas#endif
51165743Sdas
52165743Sdastypedef unsigned Long Ulong;
53165743Sdas
54165743Sdas#undef HAVE_IEEE
55165743Sdas#ifdef IEEE_8087
56165743Sdas#define _0 1
57165743Sdas#define _1 0
58165743Sdas#define HAVE_IEEE
59165743Sdas#endif
60165743Sdas#ifdef IEEE_MC68k
61165743Sdas#define _0 0
62165743Sdas#define _1 1
63165743Sdas#define HAVE_IEEE
64165743Sdas#endif
65165743Sdas
66165743Sdas#define UL (unsigned long)
67165743Sdas
68165743Sdas int
69165743Sdasmain(void)
70165743Sdas{
71165743Sdas#ifdef HAVE_IEEE
72165743Sdas	typedef union {
73165743Sdas		float f;
74165743Sdas		double d;
75165743Sdas		Ulong L[4];
76165743Sdas#ifndef NO_LONG_LONG
77165743Sdas		unsigned short u[5];
78165743Sdas		long double D;
79165743Sdas#endif
80165743Sdas		} U;
81165743Sdas	U a, b, c;
82165743Sdas	int i;
83165743Sdas
84165743Sdas	a.L[0] = b.L[0] = 0x7f800000;
85165743Sdas	c.f = a.f - b.f;
86165743Sdas	printf("#define f_QNAN 0x%lx\n", UL c.L[0]);
87165743Sdas	a.L[_0] = b.L[_0] = 0x7ff00000;
88165743Sdas	a.L[_1] = b.L[_1] = 0;
89165743Sdas	c.d = a.d - b.d;	/* quiet NaN */
90165743Sdas	printf("#define d_QNAN0 0x%lx\n", UL c.L[0]);
91165743Sdas	printf("#define d_QNAN1 0x%lx\n", UL c.L[1]);
92165743Sdas#ifdef NO_LONG_LONG
93165743Sdas	for(i = 0; i < 4; i++)
94165743Sdas		printf("#define ld_QNAN%d 0xffffffff\n", i);
95165743Sdas	for(i = 0; i < 5; i++)
96165743Sdas		printf("#define ldus_QNAN%d 0xffff\n", i);
97165743Sdas#else
98165743Sdas	b.D = c.D = a.d;
99165743Sdas	if (printf("") < 0)
100165743Sdas		c.D = 37;	/* never executed; just defeat optimization */
101165743Sdas	a.L[2] = a.L[3] = 0;
102165743Sdas	a.D = b.D - c.D;
103165743Sdas	for(i = 0; i < 4; i++)
104165743Sdas		printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]);
105165743Sdas	for(i = 0; i < 5; i++)
106165743Sdas		printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]);
107165743Sdas#endif
108165743Sdas#endif /* HAVE_IEEE */
109165743Sdas	return 0;
110165743Sdas	}
111