| 1 | /**************************************************************** |
| 2 | |
| 3 | The author of this software is David M. Gay. |
| 4 | |
| 5 | Copyright (C) 2005 by David M. Gay |
| 6 | All Rights Reserved |
| 7 | |
| 8 | Permission to use, copy, modify, and distribute this software and its |
| 9 | documentation for any purpose and without fee is hereby granted, |
| 10 | provided that the above copyright notice appear in all copies and that |
| 11 | both that the copyright notice and this permission notice and warranty |
| 12 | disclaimer appear in supporting documentation, and that the name of |
| 13 | the author or any of his current or former employers not be used in |
| 14 | advertising or publicity pertaining to distribution of the software |
| 15 | without specific, written prior permission. |
| 16 | |
| 17 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
| 18 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN |
| 19 | NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE |
| 20 | LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY |
| 21 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
| 22 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
| 23 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
| 24 | SOFTWARE. |
| 25 | |
| 26 | ****************************************************************/ |
| 27 | |
| 28 | /* Please send bug reports to David M. Gay (dmg at acm dot org, |
| 29 | * with " at " changed at "@" and " dot " changed to ".").	*/ |
| 30 | |
| 31 | /* Program to compute quiet NaNs of various precisions (float,	*/ |
| 32 | /* double, and perhaps long double) on the current system,	*/ |
| 33 | /* provided the system uses binary IEEE (P754) arithmetic.	*/ |
| 34 | /* Note that one system's quiet NaN may be a signaling NaN on	*/ |
| 35 | /* another system. The IEEE arithmetic standards (P754, P854)	*/ |
| 36 | /* do not specify how to distinguish signaling NaNs from quiet	*/ |
| 37 | /* ones, and this detail varies across systems.	 The computed	*/ |
| 38 | /* NaN values are encoded in #defines for values for an		*/ |
| 39 | /* unsigned 32-bit integer type, called Ulong below, and	*/ |
| 40 | /* (for long double) perhaps as unsigned short values. Once	*/ |
| 41 | /* upon a time, there were PC compilers for Intel CPUs that	*/ |
| 42 | /* had sizeof(long double) = 10. Are such compilers still	*/ |
| 43 | /* distributed?							*/ |
| 44 | |
| 45 | #include <stdio.h> |
| 46 | #include "gd_arith.h" |
| 47 | |
| 48 | #ifndef Long |
| 49 | #define Long long |
| 50 | #endif |
| 51 | |
| 52 | typedef unsigned Long Ulong; |
| 53 | |
| 54 | #ifdef NO_LONG_LONG |
| 55 | #undef Gen_ld_QNAN |
| 56 | #endif |
| 57 | |
| 58 | #undef HAVE_IEEE |
| 59 | #ifdef IEEE_8087 |
| 60 | #define _0 1 |
| 61 | #define _1 0 |
| 62 | #ifdef Gen_ld_QNAN |
| 63 | #define _3 3 |
| 64 | static int perm[4] = { 0, 1, 2, 3 }; |
| 65 | #endif |
| 66 | #define HAVE_IEEE |
| 67 | #endif |
| 68 | #ifdef IEEE_MC68k |
| 69 | #define _0 0 |
| 70 | #define _1 1 |
| 71 | #ifdef Gen_ld_QNAN |
| 72 | #define _3 0 |
| 73 | static int perm[4] = { 3, 2, 1, 0 }; |
| 74 | #endif |
| 75 | #define HAVE_IEEE |
| 76 | #endif |
| 77 | |
| 78 | #define UL (unsigned long) |
| 79 | |
| 80 | #ifdef MINGW_BUILD_GEN |
| 81 | int |
| 82 | main(void) |
| 83 | { |
| 84 | #ifdef HAVE_IEEE |
| 85 | 	typedef union { |
| 86 | 		float f; |
| 87 | 		double d; |
| 88 | 		Ulong L[4]; |
| 89 | #ifndef NO_LONG_LONG |
| 90 | 		unsigned short u[5]; |
| 91 | 		long double D; |
| 92 | #endif |
| 93 | 		} U; |
| 94 | 	U a, b, c; |
| 95 | #ifdef Gen_ld_QNAN |
| 96 | 	int i; |
| 97 | #endif |
| 98 | |
| 99 | 	a.L[0] = b.L[0] = 0x7f800000; |
| 100 | 	c.f = a.f - b.f; |
| 101 | 	printf("#define f_QNAN 0x%lx\n", UL (c.L[0] & 0x7fffffff)); |
| 102 | 	a.L[_0] = b.L[_0] = 0x7ff00000; |
| 103 | 	a.L[_1] = b.L[_1] = 0; |
| 104 | 	c.d = a.d - b.d;	/* quiet NaN */ |
| 105 | 	c.L[_0] &= 0x7fffffff; |
| 106 | 	printf("#define d_QNAN0 0x%lx\n", UL c.L[0]); |
| 107 | 	printf("#define d_QNAN1 0x%lx\n", UL c.L[1]); |
| 108 | #ifdef Gen_ld_QNAN |
| 109 | 	if (sizeof(a.D) >= 16) { |
| 110 | 		b.D = c.D = a.d; |
| 111 | 		if (printf("") < 0) |
| 112 | 			c.D = 37;	/* never executed; just defeat optimization */ |
| 113 | 		a.L[0] = a.L[1] = a.L[2] = a.L[3] = 0; |
| 114 | 		a.D = b.D - c.D; |
| 115 | 		a.L[_3] &= 0x7fffffff; |
| 116 | 		for(i = 0; i < 4; i++) |
| 117 | 			printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[perm[i]]); |
| 118 | 		} |
| 119 | #endif |
| 120 | #endif /* HAVE_IEEE */ |
| 121 | 	return 0; |
| 122 | 	} |
| 123 | #endif |