This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Two nits not show by mlint
[metaconfig.git] / U / perl / mantbits.U
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:longdblmantbits doublemantbits nvmantbits: Inlibc cat Compile run \
9         rm_try Setvar echo i_float i_sunmath usequadmath \
10         d_longdbl longdblkind nvsize doublesize longdblsize
11 ?MAKE:  -pick add $@ %<
12 ?S:doublemantbits:
13 ?S:     This symbol, if defined, tells how many mantissa bits
14 ?S:     there are in double precision floating point format.
15 ?S:     Note that this is usually DBL_MANT_DIG minus one, since
16 ?S:     with the standard IEEE 754 formats DBL_MANT_DIG includes
17 ?S:     the implicit bit which doesn't really exist.
18 ?S:.
19 ?S:longdblmantbits:
20 ?S:     This symbol, if defined, tells how many mantissa bits
21 ?S:     there are in long double precision floating point format.
22 ?S:     Note that this can be LDBL_MANT_DIG minus one,
23 ?S:     since LDBL_MANT_DIG can include the IEEE 754 implicit bit.
24 ?S:     The common x86-style 80-bit long double does not have
25 ?S:     an implicit bit.
26 ?S:.
27 ?S:nvmantbits:
28 ?S:     This variable tells how many bits the mantissa of a Perl NV has,
29 ?S:     not including the possible implicit bit.
30 ?S:.
31 ?C:DOUBLEMANTBITS:
32 ?C:     This symbol, if defined, tells how many mantissa bits
33 ?C:     there are in double precision floating point format.
34 ?C:     Note that this is usually DBL_MANT_DIG minus one, since
35 ?C:     with the standard IEEE 754 formats DBL_MANT_DIG includes
36 ?C:     the implicit bit, which doesn't really exist.
37 ?C:.
38 ?C:LONGDBLMANTBITS:
39 ?C:     This symbol, if defined, tells how many mantissa bits
40 ?C:     there are in long double precision floating point format.
41 ?C:     Note that this can be LDBL_MANT_DIG minus one,
42 ?C:     since LDBL_MANT_DIG can include the IEEE 754 implicit bit.
43 ?C:     The common x86-style 80-bit long double does not have
44 ?C:     an implicit bit.
45 ?C:.
46 ?C:NVMANTBITS:
47 ?C:     This symbol, if defined, tells how many mantissa bits
48 ?C:     (not including implicit bit) there are in a Perl NV.
49 ?C:     This depends on which floating point type was chosen.
50 ?C:.
51 ?H:#define DOUBLEMANTBITS  $doublemantbits
52 ?H:#define LONGDBLMANTBITS $longdblmantbits
53 ?H:#define NVMANTBITS      $nvmantbits
54 ?H:.
55 ?F:!try
56 : Check the length of the double mantissa
57 $echo "Checking how many mantissa bits your doubles have..." >&4
58 $cat >try.c <<EOP
59 #$i_float I_FLOAT
60 #$i_sunmath I_SUNMATH
61 #ifdef I_FLOAT
62 # include <float.h>
63 #endif
64 #ifdef I_SUNMATH
65 # include <sunmath.h>
66 #endif
67 #ifdef DBL_MANT_DIG
68 # define BITS (DBL_MANT_DIG - 1) /* the implicit bit does not count */
69 #endif
70 #include <stdio.h>
71 int main(int argc, char *argv[]) {
72 #ifdef BITS
73   printf("%d\n", BITS);
74 #endif
75   return 0;
76 }
77 EOP
78 set try
79 if eval $compile; then
80     doublemantbits=`$run ./try`
81 else
82     doublemantbits="$undef"
83 fi
84 $rm_try
85
86 : Check the length of the longdouble mantissa
87 $echo "Checking how many mantissa bits your long doubles have..." >&4
88 $cat >try.c <<EOP
89 #$i_float I_FLOAT
90 #$i_sunmath I_SUNMATH
91 #ifdef I_FLOAT
92 # include <float.h>
93 #endif
94 #ifdef I_SUNMATH
95 # include <sunmath.h>
96 #endif
97 #$d_longdbl HAS_LONG_DOUBLE
98 #if defined(HAS_LONG_DOUBLE) && defined(LDBL_MANT_DIG)
99 # if ($longdblkind == 3) || ($longdblkind == 4) /* 80-bit extended precision */
100 /* This format has no implicit bit.  Beware, however, that for
101  * this format the bare LDBL_MANT_DIG is misleading for inf/nan:
102  * the top three bits are used for inf (100) / qnan (11x) / snan (101),
103  * and the top bit must have been one since 387, zero is plain invalid.
104  * For normal fp values, the LDBL_MANT_DIG is fine, though. */
105 #  define BITS LDBL_MANT_DIG
106 # elif ($longdblkind == 5 || $longdblkind == 6) /* double double */
107 /* LDBL_MANT_DIG of 106 (twice 53) would be logical, but for some
108  * reason e.g. Irix thinks 107.  But in any case, we want only
109  * the number of real bits, the implicit bits are of no interest.  */
110 #  define BITS 2 * (DBL_MANT_DIG - 1)
111 # else
112 #  define BITS (LDBL_MANT_DIG - 1) /* the implicit bit does not count */
113 # endif
114 #endif
115 #include <stdio.h>
116 int main(int argc, char *argv[]) {
117 #ifdef BITS
118   printf("%d\n", BITS);
119 #endif
120   return 0;
121 }
122 EOP
123 set try
124 if eval $compile; then
125     longdblmantbits=`$run ./try`
126 else
127     longdblmantbits="$undef"
128 fi
129 $rm_try
130
131 : Check the length of the NV mantissa
132 $echo "Checking how many mantissa bits your NVs have..." >&4
133 if test "X$usequadmath" = "X$define"; then
134   nvmantbits=112 # 128-1-15
135 else
136   if test "X$nvsize" = "X$doublesize"; then
137     nvmantbits="$doublemantbits"
138   else
139      if test "X$nvsize" = "X$longdblsize"; then
140        nvmantbits="$longdblmantbits"
141      else
142        nvmantbits="$undef"
143      fi
144   fi
145 fi
146