3 ?RCS: Copyright (c) 1999-2016 Jarkko Hietaniemi
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.
8 ?MAKE:d_PRIfldbl sPRIfldbl d_PRIgldbl d_PRIFUldbl sPRIGUldbl d_PRIEUldbl \
9 sPRIgldbl d_PRIeldbl sPRIeldbl sPRIFUldbl d_PRIGUldbl sPRIEUldbl \
10 d_SCNfldbl d_double_style_vax d_double_style_ieee \
11 d_double_style_ibm d_double_style_cray d_double_has_subnormals \
12 d_double_has_inf d_double_has_nan d_double_has_negative_zero \
13 sSCNfldbl doublekind: \
14 d_longdbl longdblsize doublesize uselongdouble test echo cat rm_try \
15 Setvar Compile run i_stdlib osname gccversion ccflags
16 ?MAKE: -pick add $@ %<
18 ?S: This variable, if defined, encodes the type of a double:
19 ?S: 1 = IEEE 754 32-bit little endian,
20 ?S: 2 = IEEE 754 32-bit big endian,
21 ?S: 3 = IEEE 754 64-bit little endian,
22 ?S: 4 = IEEE 754 64-bit big endian,
23 ?S: 5 = IEEE 754 128-bit little endian,
24 ?S: 6 = IEEE 754 128-bit big endian,
25 ?S: 7 = IEEE 754 64-bit mixed endian le-be,
26 ?S: 8 = IEEE 754 64-bit mixed endian be-le,
27 ?S: 9 = VAX 32bit little endian F float format
28 ?S: 10 = VAX 64bit little endian D float format
29 ?S: 11 = VAX 64bit little endian G float format
30 ?S: 12 = IBM 32bit format
31 ?S: 13 = IBM 64bit format
32 ?S: 14 = Cray 64bit format
33 ?S: -1 = unknown format.
36 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
37 ?S: indicates that stdio has a symbol to print long doubles.
40 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
41 ?S: indicates that stdio has a symbol to print long doubles.
44 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
45 ?S: indicates that stdio has a symbol to print long doubles.
48 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
49 ?S: indicates that stdio has a symbol to print long doubles.
50 ?S: The 'U' in the name is to separate this from d_PRIfldbl so that even
51 ?S: case-blind systems can see the difference.
54 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
55 ?S: indicates that stdio has a symbol to print long doubles.
56 ?S: The 'U' in the name is to separate this from d_PRIgldbl so that even
57 ?S: case-blind systems can see the difference.
60 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
61 ?S: indicates that stdio has a symbol to print long doubles.
62 ?S: The 'U' in the name is to separate this from d_PRIeldbl so that even
63 ?S: case-blind systems can see the difference.
66 ?S: This variable conditionally defines the PERL_PRIfldbl symbol, which
67 ?S: indicates that stdio has a symbol to scan long doubles.
70 ?S: This variable, if defined, contains the string used by stdio to
71 ?S: format long doubles (format 'f') for output.
74 ?S: This variable, if defined, contains the string used by stdio to
75 ?S: format long doubles (format 'g') for output.
78 ?S: This variable, if defined, contains the string used by stdio to
79 ?S: format long doubles (format 'e') for output.
82 ?S: This variable, if defined, contains the string used by stdio to
83 ?S: format long doubles (format 'F') for output.
84 ?S: The 'U' in the name is to separate this from sPRIfldbl so that even
85 ?S: case-blind systems can see the difference.
88 ?S: This variable, if defined, contains the string used by stdio to
89 ?S: format long doubles (format 'G') for output.
90 ?S: The 'U' in the name is to separate this from sPRIgldbl so that even
91 ?S: case-blind systems can see the difference.
94 ?S: This variable, if defined, contains the string used by stdio to
95 ?S: format long doubles (format 'E') for output.
96 ?S: The 'U' in the name is to separate this from sPRIeldbl so that even
97 ?S: case-blind systems can see the difference.
100 ?S: This variable, if defined, contains the string used by stdio to
101 ?S: format long doubles (format 'f') for input.
104 ?S: This variable conditionally defines the symbol DOUBLE_HAS_INF
105 ?S: which indicates that the double type has an infinity.
108 ?S: This variable conditionally defines the symbol DOUBLE_HAS_NAN
109 ?S: which indicates that the double type has a not-a-number.
111 ?S:d_double_has_negative_zero:
112 ?S: This variable conditionally defines the symbol DOUBLE_HAS_NEGATIVE_ZERO
113 ?S: which indicates that the double type has a negative zero.
115 ?S:d_double_has_subnormals:
116 ?S: This variable conditionally defines the symbol DOUBLE_HAS_SUBNORMALS
117 ?S: which indicates that the double type has subnormals (denormals).
119 ?S:d_double_style_cray:
120 ?S: This variable conditionally defines the symbol DOUBLE_STYLE_CRAY
121 ?S: which indicates that the double is the 64-bit CRAY mainframe format.
123 ?S:d_double_style_ibm:
124 ?S: This variable conditionally defines the symbol DOUBLE_STYLE_IBM,
125 ?S: which indicates that the double is the 64-bit IBM mainframe format.
127 ?S:d_double_style_ieee:
128 ?S: This variable conditionally defines the symbol DOUBLE_STYLE_IEEE,
129 ?S: which indicates that the double is the 64-bit IEEE 754.
131 ?S:d_double_style_vax:
132 ?S: This variable conditionally defines the symbol DOUBLE_STYLE_VAX,
133 ?S: which indicates that the double is the 64-bit VAX format D or G.
136 ?C: This symbol, if defined, contains the string used by stdio to
137 ?C: format long doubles (format 'f') for output.
140 ?C: This symbol, if defined, contains the string used by stdio to
141 ?C: format long doubles (format 'g') for output.
144 ?C: This symbol, if defined, contains the string used by stdio to
145 ?C: format long doubles (format 'e') for output.
148 ?C: This symbol, if defined, contains the string used by stdio to
149 ?C: format long doubles (format 'f') for output.
152 ?C: This symbol, if defined, contains the string used by stdio to
153 ?C: format long doubles (format 'g') for output.
156 ?C: This symbol, if defined, contains the string used by stdio to
157 ?C: format long doubles (format 'e') for output.
160 ?C: This symbol, if defined, contains the string used by stdio to
161 ?C: format long doubles (format 'f') for input.
164 ?C: DOUBLEKIND will be one of
165 ?C: DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN
166 ?C: DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN
167 ?C: DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN
168 ?C: DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN
169 ?C: DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
170 ?C: DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
171 ?C: DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE
172 ?C: DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
173 ?C: DOUBLE_IS_VAX_F_FLOAT
174 ?C: DOUBLE_IS_VAX_D_FLOAT
175 ?C: DOUBLE_IS_VAX_G_FLOAT
176 ?C: DOUBLE_IS_IBM_SINGLE_32_BIT
177 ?C: DOUBLE_IS_IBM_DOUBLE_64_BIT
178 ?C: DOUBLE_IS_CRAY_SINGLE_64_BIT
179 ?C: DOUBLE_IS_UNKNOWN_FORMAT
182 ?C: This symbol, if defined, indicates that the double has
186 ?C: This symbol, if defined, indicates that the double has
187 ?C: the not-a-number.
189 ?C:DOUBLE_HAS_NEGATIVE_ZERO:
190 ?C: This symbol, if defined, indicates that the double has
191 ?C: the negative_zero.
193 ?C:DOUBLE_HAS_SUBNORMALS:
194 ?C: This symbol, if defined, indicates that the double has
195 ?C: the subnormals (denormals).
197 ?C:DOUBLE_STYLE_CRAY:
198 ?C: This symbol, if defined, indicates that the double is
199 ?C: the 64-bit CRAY mainframe format.
202 ?C: This symbol, if defined, indicates that the double is
203 ?C: the 64-bit IBM mainframe format.
205 ?C:DOUBLE_STYLE_IEEE:
206 ?C: This symbol, if defined, indicates that the double is
207 ?C: the 64-bit IEEE 754.
210 ?C: This symbol, if defined, indicates that the double is
211 ?C: the 64-bit VAX format D or G.
213 ?LINT:known DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN
214 ?LINT:known DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN
215 ?LINT:known DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN
216 ?LINT:known DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN
217 ?LINT:known DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
218 ?LINT:known DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
219 ?LINT:known DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE
220 ?LINT:known DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
221 ?LINT:known DOUBLE_IS_VAX_F_FLOAT
222 ?LINT:known DOUBLE_IS_VAX_D_FLOAT
223 ?LINT:known DOUBLE_IS_VAX_G_FLOAT
224 ?LINT:known DOUBLE_IS_IBM_SINGLE_32_BIT
225 ?LINT:known DOUBLE_IS_IBM_DOUBLE_64_BIT
226 ?LINT:known DOUBLE_IS_CRAY_SINGLE_64_BIT
227 ?LINT:known DOUBLE_IS_UNKNOWN_FORMAT
228 ?H:#define DOUBLEKIND $doublekind /**/
229 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN 1
230 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN 2
231 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN 3
232 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN 4
233 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN 5
234 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN 6
235 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE 7
236 ?H:?DOUBLEKIND:#define DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE 8
237 ?H:?DOUBLEKIND:#define DOUBLE_IS_VAX_F_FLOAT 9
238 ?H:?DOUBLEKIND:#define DOUBLE_IS_VAX_D_FLOAT 10
239 ?H:?DOUBLEKIND:#define DOUBLE_IS_VAX_G_FLOAT 11
240 ?H:?DOUBLEKIND:#define DOUBLE_IS_IBM_SINGLE_32_BIT 12
241 ?H:?DOUBLEKIND:#define DOUBLE_IS_IBM_DOUBLE_64_BIT 13
242 ?H:?DOUBLEKIND:#define DOUBLE_IS_CRAY_SINGLE_64_BIT 14
243 ?H:?DOUBLEKIND:#define DOUBLE_IS_UNKNOWN_FORMAT -1
244 ?H:#$d_PRIfldbl PERL_PRIfldbl $sPRIfldbl /**/
245 ?H:#$d_PRIgldbl PERL_PRIgldbl $sPRIgldbl /**/
246 ?H:#$d_PRIeldbl PERL_PRIeldbl $sPRIeldbl /**/
247 ?H:#$d_PRIFUldbl PERL_PRIFldbl $sPRIFUldbl /**/
248 ?H:#$d_PRIGUldbl PERL_PRIGldbl $sPRIGUldbl /**/
249 ?H:#$d_PRIEUldbl PERL_PRIEldbl $sPRIEUldbl /**/
250 ?H:#$d_SCNfldbl PERL_SCNfldbl $sSCNfldbl /**/
251 ?H:#$d_double_has_inf DOUBLE_HAS_INF
252 ?H:#$d_double_has_nan DOUBLE_HAS_NAN
253 ?H:#$d_double_has_negative_zero DOUBLE_HAS_NEGATIVE_ZERO
254 ?H:#$d_double_has_subnormals DOUBLE_HAS_SUBNORMALS
255 ?H:#$d_double_style_cray DOUBLE_STYLE_CRAY
256 ?H:#$d_double_style_ibm DOUBLE_STYLE_IBM
257 ?H:#$d_double_style_ieee DOUBLE_STYLE_IEEE
258 ?H:#$d_double_style_vax DOUBLE_STYLE_VAX
260 ?T:yyy message saveccflags
263 ?LINT:change uselongdouble
264 : Check what kind of doubles your system has
265 $echo "Checking the kind of doubles you have..." >&4
268 #define DOUBLESIZE $doublesize
273 static const double d = -0.1;
275 unsigned const char* b = (unsigned const char*)(&d);
277 if (b[0] == 0xCD && b[3] == 0xBD) {
278 /* IEEE 754 32-bit little-endian */
282 if (b[0] == 0xBD && b[3] == 0xCD) {
283 /* IEEE 754 32-bit big-endian */
287 if (b[0] == 0xCC && b[3] == 0xCC) {
288 /* VAX format F, 32-bit PDP-style mixed endian. */
292 if (b[0] == 0xC0 && b[3] == 0x9A) {
293 /* IBM single 32-bit */
299 if (b[0] == 0x9A && b[7] == 0xBF) {
300 /* IEEE 754 64-bit little-endian */
304 if (b[0] == 0xBF && b[7] == 0x9A) {
305 /* IEEE 754 64-bit big-endian */
309 if (b[0] == 0x99 && b[3] == 0xBF && b[4] == 0x9A && b[7] == 0x99) {
310 /* ARM mixed endian: two little-endian 32-bit floats, in big endian order:
311 * 4 5 6 7 0 1 2 3 (MSB = 7, LSB = 0)
312 * 99 99 b9 bf 9a 99 99 99 */
316 if (b[0] == 0x99 && b[3] == 0x9A && b[4] == 0xBF && b[7] == 0x99) {
317 /* The opposite of case 7, mixed endian: two big-endian 32-bit floats,
318 * in little endian order: 3 2 1 0 7 6 5 4 (MSB = 7, LSB = 0)
319 * 99 99 99 9a bf b9 99 99 */
323 if (b[0] == 0xCC && b[7] == 0xCC) {
324 /* VAX format D, 64-bit PDP-style mixed endian. */
328 if (b[0] == 0xD9 && b[7] == 0x99) {
329 /* VAX format G, 64-bit PDP-style mixed endian. */
333 if (b[0] == 0xC0 && b[7] == 0x9A) {
334 /* IBM double 64-bit */
338 if (b[0] == 0xBF && b[7] == 0xCD) {
339 /* CRAY single 64-bit */
345 if (b[0] == 0x9A && b[15] == 0xBF) {
346 /* IEEE 754 128-bit little-endian */
350 if (b[0] == 0xBF && b[15] == 0x9A) {
351 /* IEEE 754 128-bit big-endian */
356 /* Then there are old mainframe/miniframe formats like IBM and CRAY.
357 * Whether those environments can still build Perl is debatable. */
358 printf("-1\n"); /* unknown */
363 if eval $compile; then
364 doublekind=`$run ./try`
368 case "$doublekind" in
369 1) echo "You have IEEE 754 32-bit little endian doubles." >&4 ;;
370 2) echo "You have IEEE 754 32-bit big endian doubles." >&4 ;;
371 3) echo "You have IEEE 754 64-bit little endian doubles." >&4 ;;
372 4) echo "You have IEEE 754 64-bit big endian doubles." >&4 ;;
373 5) echo "You have IEEE 754 128-bit little endian doubles." >&4 ;;
374 6) echo "You have IEEE 754 128-bit big endian doubles." >&4 ;;
375 7) echo "You have IEEE 754 64-bit mixed endian doubles (32-bit LEs in BE)." >&4 ;;
376 8) echo "You have IEEE 754 64-bit mixed endian doubles (32-bit BEs in LE)." >&4 ;;
377 9) echo "You have VAX format F 32-bit PDP-style mixed endian doubles." >&4 ;;
378 10) echo "You have VAX format D 64-bit PDP-style mixed endian doubles." >&4 ;;
379 11) echo "You have VAX format G 64-bit PDP-style mixed endian doubles." >&4 ;;
380 12) echo "You have IBM short 32-bit doubles." >&4 ;;
381 13) echo "You have IBM long 64-bit doubles." >&4 ;;
382 14) echo "You have Cray single 64-bit doubles." >&4 ;;
383 *) echo "Cannot figure out your double. You Cyber, or something?" >&4 ;;
385 d_double_style_ieee=$undef
386 d_double_style_vax=$undef
387 d_double_style_ibm=$undef
388 d_double_style_cray=$undef
389 case "$doublekind" in
390 1|2|3|4|5|6|7|8) d_double_style_ieee=$define ;;
391 9|10|11) d_double_style_vax=$define ;;
392 12|13) d_double_style_ibm=$define ;;
393 14) d_double_style_cray=$define ;;
395 case "$d_double_style_ieee" in
397 d_double_has_inf=$define
398 d_double_has_nan=$define
399 d_double_has_negative_zero=$define
400 d_double_has_subnormals=$define
403 d_double_has_inf=$undef
404 d_double_has_nan=$undef
405 d_double_has_negative_zero=$undef
406 d_double_has_subnormals=$undef
411 : Check print/scan long double stuff
414 if $test X"$d_longdbl" = X"$define"; then
416 echo "Checking how to print long doubles..." >&4
418 if $test X"$sPRIfldbl" = X -a X"$doublesize" = X"$longdblsize"; then
420 #include <sys/types.h>
428 if eval $compile; then
432 sPRIfldbl='"f"'; sPRIgldbl='"g"'; sPRIeldbl='"e"';
433 sPRIFUldbl='"F"'; sPRIGUldbl='"G"'; sPRIEUldbl='"E"';
434 echo "We will use %f."
440 if $test X"$sPRIfldbl" = X; then
442 #include <sys/types.h>
445 long double d = 123.456;
446 printf("%.3Lf\n", d);
450 if eval $compile; then
454 sPRIfldbl='"Lf"'; sPRIgldbl='"Lg"'; sPRIeldbl='"Le"';
455 sPRIFUldbl='"LF"'; sPRIGUldbl='"LG"'; sPRIEUldbl='"LE"';
456 echo "We will use %Lf."
462 if $test X"$sPRIfldbl" = X; then
464 #include <sys/types.h>
467 long double d = 123.456;
468 printf("%.3llf\n", d);
472 if eval $compile; then
476 sPRIfldbl='"llf"'; sPRIgldbl='"llg"'; sPRIeldbl='"lle"';
477 sPRIFUldbl='"llF"'; sPRIGUldbl='"llG"'; sPRIEUldbl='"llE"';
478 echo "We will use %llf."
484 if $test X"$sPRIfldbl" = X; then
486 #include <sys/types.h>
489 long double d = 123.456;
490 printf("%.3lf\n", d);
494 if eval $compile; then
498 sPRIfldbl='"lf"'; sPRIgldbl='"lg"'; sPRIeldbl='"le"';
499 sPRIFUldbl='"lF"'; sPRIGUldbl='"lG"'; sPRIEUldbl='"lE"';
500 echo "We will use %lf."
506 if $test X"$sPRIfldbl" = X; then
507 echo "Cannot figure out how to print long doubles." >&4
509 sSCNfldbl=$sPRIfldbl # expect consistency
517 '') d_PRIfldbl="$undef"; d_PRIgldbl="$undef"; d_PRIeldbl="$undef";
518 d_PRIFUldbl="$undef"; d_PRIGUldbl="$undef"; d_PRIEUldbl="$undef";
521 *) d_PRIfldbl="$define"; d_PRIgldbl="$define"; d_PRIeldbl="$define";
522 d_PRIFUldbl="$define"; d_PRIGUldbl="$define"; d_PRIEUldbl="$define";
523 d_SCNfldbl="$define";
527 : Before committing on uselongdouble, see whether that looks sane.
528 if $test "$uselongdouble" = "$define"; then
531 echo "Checking if your long double math functions work right..." >&4
536 printf("%"$sPRIgldbl"\n", sqrtl(logl(expl(cosl(sinl(0.0L))))+powl(2.0L, 3.0L)));
539 case "$osname:$gccversion" in
540 aix:) saveccflags="$ccflags"
541 ccflags="$ccflags -qlongdouble" ;; # to avoid core dump
544 if eval $compile_ok; then
548 3) echo "Your long double math functions are working correctly." >&4 ;;
549 *) echo "Your long double math functions are broken, not using long doubles." >&4
554 case "$osname:$gccversion" in
555 aix:) ccflags="$saveccflags" ;; # restore