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