Commit | Line | Data |
---|---|---|
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 \ | |
9 | cat i_math Compile run rm_try Setvar echo d_longdbl \ | |
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 | |
61 | #ifdef I_MATH | |
62 | #include <math.h> | |
63 | #endif | |
64 | #include <stdio.h> | |
65 | /* Note that whether the sign bit is on or off | |
66 | * for NaN depends on the CPU/FPU, and possibly | |
67 | * can be affected by the build toolchain. | |
68 | * | |
69 | * For example for older MIPS and HP-PA 2.0 the quiet NaN is: | |
70 | * 0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
71 | * 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
72 | * (respectively) as opposed to the more usual | |
73 | * 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
3db366a3 MBT |
74 | * |
75 | * Pre-IEEE-754 floating point format do not even have inf/nan support | |
76 | * at all. They might have a "max" value (DBL_MAX), which may be deadly | |
77 | * to even mention, causing immediate SIGFPE or equivalent: this is | |
78 | * the case with VAX floating point, for example. | |
8998a849 MBT |
79 | */ |
80 | static void bytes(unsigned char *p, unsigned int n) { | |
81 | int i; | |
82 | for (i = 0; i < n; i++) { | |
83 | printf("0x%02x%s", p[i], i < n - 1 ? ", " : "\n"); | |
84 | } | |
85 | } | |
86 | int main(int argc, char *argv[]) { | |
87 | /* We cannot use 1.0/0.0 and 0.0/0.0 (with L suffixes for long double) | |
88 | * because some compilers are 'smart' and not only warn but refuse to | |
89 | * compile such 'illegal' values. */ | |
90 | double dinf = exp(1e9); | |
91 | double dnan = sqrt(-1.0); | |
92 | #ifdef HAS_LONG_DOUBLE | |
93 | long double ldinf = (long double)exp(1e9); | |
94 | long double ldnan = (long double)sqrt(-1.0); | |
8998a849 MBT |
95 | # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4 |
96 | /* the 80-bit long doubles might have garbage in their excess bytes */ | |
97 | memset((char *)&ldinf + 10, '\0', LONG_DOUBLESIZE - 10); | |
2b190d47 | 98 | memset((char *)&ldnan + 10, '\0', LONG_DOUBLESIZE - 10); |
8998a849 | 99 | # endif |
2b190d47 MBT |
100 | if (argc == 2) { |
101 | switch (argv[1][0]) { | |
102 | case '1': bytes(&dinf, sizeof(dinf)); break; | |
103 | case '2': bytes(&dnan, sizeof(dnan)); break; | |
8998a849 MBT |
104 | case '3': bytes(&ldinf, sizeof(ldinf)); break; |
105 | case '4': bytes(&ldnan, sizeof(ldnan)); break; | |
106 | #endif | |
107 | } | |
108 | } | |
109 | return 0; | |
110 | } | |
111 | EOP | |
112 | set try | |
113 | if eval $compile; then | |
114 | doubleinfbytes=`$run ./try 1` | |
115 | doublenanbytes=`$run ./try 2` | |
116 | case "$d_longdbl" in | |
117 | $define) | |
118 | longdblinfbytes=`$run ./try 3` | |
119 | longdblnanbytes=`$run ./try 4` | |
120 | ;; | |
121 | esac | |
122 | else | |
123 | # Defaults in case the above test program failed. | |
124 | case "$doublekind" in | |
125 | 1) # IEEE 754 32-bit LE | |
126 | doubleinfbytes='0x00, 0x00, 0xf0, 0x7f' | |
127 | doublenanbytes='0x00, 0x00, 0xf8, 0x7f' | |
128 | ;; | |
129 | 2) # IEEE 754 32-bit BE | |
130 | doubleinfbytes='0x7f, 0xf0, 0x00, 0x00' | |
131 | doublenanbytes='0x7f, 0xf8, 0x00, 0x00' | |
132 | ;; | |
133 | 3) # IEEE 754 64-bit LE | |
134 | doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' | |
135 | doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' | |
136 | ;; | |
137 | 4) # IEEE 754 64-bit BE | |
138 | doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
139 | doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
140 | ;; | |
141 | 5) # IEEE 754 128-bit LE | |
142 | doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' | |
143 | doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' | |
144 | ;; | |
145 | 6) # IEEE 754 128-bit BE | |
146 | doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
147 | doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
148 | ;; | |
149 | 7) # IEEE 754 64-bit mixed: 32-bit LEs in BE | |
150 | doubleinfbytes='0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00' | |
151 | doublenanbytes='0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00' | |
152 | ;; | |
153 | 8) # IEEE 754 64-bit mixed: 32-bit BEs in LE | |
154 | doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00' | |
155 | doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00' | |
156 | ;; | |
3db366a3 MBT |
157 | 9|10|11|12|13|14) # VAX/Cray/IBM floating point formats, no inf/nan. |
158 | doubleinfbytes=$undef | |
159 | doublenanbytes=$undef | |
160 | ;; | |
8998a849 MBT |
161 | *) # No idea. |
162 | doubleinfbytes=$undef | |
163 | doublenanbytes=$undef | |
164 | ;; | |
165 | esac | |
166 | case "$longdblkind" in | |
167 | 1) # IEEE 754 128-bit LE | |
168 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f' | |
169 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f' | |
170 | ;; | |
171 | 2) # IEEE 754 128-bit BE | |
172 | longdblinfbytes='0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
173 | longdblnanbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
174 | ;; | |
175 | 3) # IEEE 754 80-bit LE, 12 or 16 bytes (x86) | |
176 | case "$longdblsize" in | |
177 | 12) # x86 32-bit (96 bits, or 4 x 32, or 12 x 8) | |
178 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00' | |
179 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00' | |
180 | ;; | |
181 | 16) # x86_64 | |
182 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
183 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
184 | ;; | |
185 | *) # No idea. | |
186 | longdblinfbytes=$undef | |
187 | longdblnanbytes=$undef | |
188 | ;; | |
189 | esac | |
190 | ;; | |
191 | 4) # IEEE 754 80-bit BE, 12 or 16 bytes | |
192 | case "$longdblsize" in | |
193 | 12) # 32-bit system | |
194 | longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
195 | longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
196 | ;; | |
197 | 16) # 64-bit system | |
198 | longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
199 | longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
200 | ;; | |
201 | *) # No idea. | |
202 | longdblinfbytes=$undef | |
203 | longdblnanbytes=$undef | |
204 | ;; | |
205 | esac | |
206 | ;; | |
5f2a9443 | 207 | 5) # 128-bit LE-LE "double double" |
8998a849 MBT |
208 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' |
209 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' | |
210 | ;; | |
5f2a9443 | 211 | 6) # 128-bit BE-BE "double double" |
8998a849 MBT |
212 | longdblinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' |
213 | longdblnanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
214 | ;; | |
5f2a9443 AC |
215 | 7) # 128-bit LE-BE "double double" |
216 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
217 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
218 | ;; | |
219 | 8) # 128-bit BE-LE "double double" | |
220 | longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
221 | longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' | |
222 | ;; | |
3db366a3 MBT |
223 | 9|10|11|12|13|14) # VAX/Cray/IBM floating point formats, no inf/nan. |
224 | longdblinfbytes=$undef | |
225 | longdblnanbytes=$undef | |
226 | ;; | |
8998a849 MBT |
227 | *) # No idea. |
228 | longdblinfbytes=$undef | |
229 | longdblnanbytes=$undef | |
230 | ;; | |
231 | esac | |
232 | fi | |
3db366a3 MBT |
233 | # In case the program crashed the values are empty, turn them undef. |
234 | case "$doubleinfbytes" in | |
235 | '') doubleinfbytes=$undef ;; | |
236 | esac | |
237 | case "$doublenanbytes" in | |
238 | '') doublenanbytes=$undef ;; | |
239 | esac | |
240 | case "$longdblinfbytes" in | |
241 | '') longdblinfbytes=$undef ;; | |
242 | esac | |
243 | case "$longdblnanbytes" in | |
244 | '') longdblnanbytes=$undef ;; | |
245 | esac | |
8998a849 MBT |
246 | $rm_try |
247 |