This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix .gitignore: only ignore 'perl' in root of repo, not U/perl subdir
[metaconfig.git] / U / perl / infnan.U
CommitLineData
8998a849
MBT
1?RCS: $Id$
2?RCS:
3?RCS: Copyright (c) 2015 Jarkko Hietaniemi, H.Merijn Brand
4?RCS:
5?RCS: You may distribute under the terms of either the GNU General Public
6?RCS: License or the Artistic License, as specified in the README file.
7?RCS:
8?MAKE:longdblinfbytes longdblnanbytes doubleinfbytes doublenanbytes: Inlibc \
fcd0577a 9 cat i_math i_string Compile run rm_try Setvar echo d_longdbl \
8998a849 10 doublekind doublesize longdblkind longdblsize
bf106bfe 11?MAKE: -pick add $@ %<
8998a849
MBT
12?S:longdblinfbytes:
13?S: This variable contains comma-separated list of hexadecimal bytes
5ca72400 14?S: for the long double precision infinity.
8998a849
MBT
15?S:.
16?S:longdblnanbytes:
17?S: This variable contains comma-separated list of hexadecimal bytes
5ca72400 18?S: for the long double precision not-a-number.
8998a849
MBT
19?S:.
20?S:doubleinfbytes:
21?S: This variable contains comma-separated list of hexadecimal bytes
5ca72400 22?S: for the double precision infinity.
8998a849
MBT
23?S:.
24?S:doublenanbytes:
25?S: This variable contains comma-separated list of hexadecimal bytes
5ca72400 26?S: for the double precision not-a-number.
8998a849
MBT
27?S:.
28?C:DOUBLEINFBYTES:
29?C: This symbol, if defined, is a comma-separated list of
30?C: hexadecimal bytes for the double precision infinity.
31?C:.
32?C:DOUBLENANBYTES:
33?C: This symbol, if defined, is a comma-separated list of
34?C: hexadecimal bytes (0xHH) for the double precision not-a-number.
35?C:.
36?C:LONGDBLINFBYTES:
37?C: This symbol, if defined, is a comma-separated list of
38?C: hexadecimal bytes for the long double precision infinity.
39?C:.
40?C:LONGDBLNANBYTES:
41?C: This symbol, if defined, is a comma-separated list of
42?C: hexadecimal bytes (0xHH) for the long double precision not-a-number.
43?C:.
44?H:#define DOUBLEINFBYTES $doubleinfbytes /**/
45?H:#define DOUBLENANBYTES $doublenanbytes /**/
46?H:#define LONGDBLINFBYTES $longdblinfbytes /**/
47?H:#define LONGDBLNANBYTES $longdblnanbytes /**/
48?H:.
49?F:!try
50: Check what kind of inf/nan your system has
51$echo "Checking the kind of infinities and nans you have..." >&4
7253d5da 52$echo "(The following tests may crash. That's okay.)" >&4
8998a849
MBT
53$cat >try.c <<EOP
54#define DOUBLESIZE $doublesize
55#$d_longdbl HAS_LONG_DOUBLE
56#ifdef HAS_LONG_DOUBLE
2b190d47
MBT
57#define LONG_DOUBLESIZE $longdblsize
58#define LONG_DOUBLEKIND $longdblkind
8998a849
MBT
59#endif
60#$i_math I_MATH
fcd0577a 61#$i_string I_STRING
8998a849
MBT
62#ifdef I_MATH
63#include <math.h>
64#endif
fcd0577a
MBT
65#ifdef I_STRING
66# include <string.h>
67#endif
8998a849
MBT
68#include <stdio.h>
69/* Note that whether the sign bit is on or off
70 * for NaN depends on the CPU/FPU, and possibly
71 * can be affected by the build toolchain.
72 *
73 * For example for older MIPS and HP-PA 2.0 the quiet NaN is:
74 * 0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
75 * 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
76 * (respectively) as opposed to the more usual
77 * 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3db366a3
MBT
78 *
79 * Pre-IEEE-754 floating point format do not even have inf/nan support
80 * at all. They might have a "max" value (DBL_MAX), which may be deadly
81 * to even mention, causing immediate SIGFPE or equivalent: this is
82 * the case with VAX floating point, for example.
8998a849 83 */
fcd0577a
MBT
84static void bytes(void *v, unsigned int n) {
85 unsigned char *p = (unsigned char *)v;
8998a849
MBT
86 int i;
87 for (i = 0; i < n; i++) {
88 printf("0x%02x%s", p[i], i < n - 1 ? ", " : "\n");
89 }
90}
91int main(int argc, char *argv[]) {
92 /* We cannot use 1.0/0.0 and 0.0/0.0 (with L suffixes for long double)
93 * because some compilers are 'smart' and not only warn but refuse to
94 * compile such 'illegal' values. */
95 double dinf = exp(1e9);
96 double dnan = sqrt(-1.0);
97#ifdef HAS_LONG_DOUBLE
98 long double ldinf = (long double)exp(1e9);
99 long double ldnan = (long double)sqrt(-1.0);
8998a849
MBT
100# if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
101/* the 80-bit long doubles might have garbage in their excess bytes */
102 memset((char *)&ldinf + 10, '\0', LONG_DOUBLESIZE - 10);
2b190d47 103 memset((char *)&ldnan + 10, '\0', LONG_DOUBLESIZE - 10);
8998a849 104# endif
2b190d47
MBT
105 if (argc == 2) {
106 switch (argv[1][0]) {
107 case '1': bytes(&dinf, sizeof(dinf)); break;
108 case '2': bytes(&dnan, sizeof(dnan)); break;
8998a849
MBT
109 case '3': bytes(&ldinf, sizeof(ldinf)); break;
110 case '4': bytes(&ldnan, sizeof(ldnan)); break;
111#endif
112 }
113 }
114 return 0;
115}
116EOP
117set try
118if eval $compile; then
119 doubleinfbytes=`$run ./try 1`
120 doublenanbytes=`$run ./try 2`
121 case "$d_longdbl" in
122 $define)
123 longdblinfbytes=`$run ./try 3`
124 longdblnanbytes=`$run ./try 4`
125 ;;
126 esac
127else
128 # Defaults in case the above test program failed.
129 case "$doublekind" in
130 1) # IEEE 754 32-bit LE
131 doubleinfbytes='0x00, 0x00, 0xf0, 0x7f'
132 doublenanbytes='0x00, 0x00, 0xf8, 0x7f'
133 ;;
134 2) # IEEE 754 32-bit BE
135 doubleinfbytes='0x7f, 0xf0, 0x00, 0x00'
136 doublenanbytes='0x7f, 0xf8, 0x00, 0x00'
137 ;;
138 3) # IEEE 754 64-bit LE
139 doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
140 doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
141 ;;
142 4) # IEEE 754 64-bit BE
143 doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
144 doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
145 ;;
146 5) # IEEE 754 128-bit LE
147 doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
148 doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
149 ;;
150 6) # IEEE 754 128-bit BE
151 doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
152 doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
153 ;;
154 7) # IEEE 754 64-bit mixed: 32-bit LEs in BE
155 doubleinfbytes='0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00'
156 doublenanbytes='0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00'
157 ;;
158 8) # IEEE 754 64-bit mixed: 32-bit BEs in LE
159 doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00'
160 doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00'
161 ;;
3db366a3
MBT
162 9|10|11|12|13|14) # VAX/Cray/IBM floating point formats, no inf/nan.
163 doubleinfbytes=$undef
164 doublenanbytes=$undef
165 ;;
8998a849
MBT
166 *) # No idea.
167 doubleinfbytes=$undef
168 doublenanbytes=$undef
169 ;;
170 esac
171 case "$longdblkind" in
172 1) # IEEE 754 128-bit LE
173 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f'
174 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f'
175 ;;
176 2) # IEEE 754 128-bit BE
177 longdblinfbytes='0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
178 longdblnanbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
179 ;;
180 3) # IEEE 754 80-bit LE, 12 or 16 bytes (x86)
181 case "$longdblsize" in
182 12) # x86 32-bit (96 bits, or 4 x 32, or 12 x 8)
183 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00'
184 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00'
185 ;;
186 16) # x86_64
187 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
188 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
189 ;;
190 *) # No idea.
191 longdblinfbytes=$undef
192 longdblnanbytes=$undef
193 ;;
194 esac
195 ;;
196 4) # IEEE 754 80-bit BE, 12 or 16 bytes
197 case "$longdblsize" in
198 12) # 32-bit system
199 longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
200 longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
201 ;;
202 16) # 64-bit system
203 longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
204 longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
205 ;;
206 *) # No idea.
207 longdblinfbytes=$undef
208 longdblnanbytes=$undef
209 ;;
210 esac
211 ;;
5f2a9443 212 5) # 128-bit LE-LE "double double"
8998a849
MBT
213 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
214 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
215 ;;
5f2a9443 216 6) # 128-bit BE-BE "double double"
8998a849
MBT
217 longdblinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
218 longdblnanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
219 ;;
5f2a9443
AC
220 7) # 128-bit LE-BE "double double"
221 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
222 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
223 ;;
224 8) # 128-bit BE-LE "double double"
225 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
226 longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
227 ;;
3db366a3
MBT
228 9|10|11|12|13|14) # VAX/Cray/IBM floating point formats, no inf/nan.
229 longdblinfbytes=$undef
230 longdblnanbytes=$undef
231 ;;
8998a849
MBT
232 *) # No idea.
233 longdblinfbytes=$undef
234 longdblnanbytes=$undef
235 ;;
236 esac
237fi
3db366a3
MBT
238# In case the program crashed the values are empty, turn them undef.
239case "$doubleinfbytes" in
240'') doubleinfbytes=$undef ;;
241esac
242case "$doublenanbytes" in
243'') doublenanbytes=$undef ;;
244esac
245case "$longdblinfbytes" in
246'') longdblinfbytes=$undef ;;
247esac
248case "$longdblnanbytes" in
249'') longdblnanbytes=$undef ;;
250esac
8998a849
MBT
251$rm_try
252