diff options
Diffstat (limited to 'gl/float.in.h')
| -rw-r--r-- | gl/float.in.h | 236 |
1 files changed, 183 insertions, 53 deletions
diff --git a/gl/float.in.h b/gl/float.in.h index 73e8d406..9f735cb9 100644 --- a/gl/float.in.h +++ b/gl/float.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A correct <float.h>. | 1 | /* A correct <float.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2026 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -28,6 +28,8 @@ | |||
| 28 | #ifndef _@GUARD_PREFIX@_FLOAT_H | 28 | #ifndef _@GUARD_PREFIX@_FLOAT_H |
| 29 | #define _@GUARD_PREFIX@_FLOAT_H | 29 | #define _@GUARD_PREFIX@_FLOAT_H |
| 30 | 30 | ||
| 31 | /* ============================ ISO C99 support ============================ */ | ||
| 32 | |||
| 31 | /* 'long double' properties. */ | 33 | /* 'long double' properties. */ |
| 32 | 34 | ||
| 33 | #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) | 35 | #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) |
| @@ -113,71 +115,199 @@ extern const union gl_long_double_union gl_LDBL_MAX; | |||
| 113 | 115 | ||
| 114 | /* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are | 116 | /* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are |
| 115 | wrong. | 117 | wrong. |
| 116 | On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ | 118 | On Linux/PowerPC with gcc 8.3, the values of LDBL_MAX and LDBL_EPSILON are |
| 117 | #if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ | 119 | wrong. |
| 120 | Assume these bugs are fixed in any GCC new enough | ||
| 121 | to define __LDBL_NORM_MAX__. */ | ||
| 122 | #if (defined _ARCH_PPC && LDBL_MANT_DIG == 106 \ | ||
| 123 | && defined __GNUC__ && !defined __LDBL_NORM_MAX__) | ||
| 118 | # undef LDBL_MIN_EXP | 124 | # undef LDBL_MIN_EXP |
| 119 | # define LDBL_MIN_EXP DBL_MIN_EXP | 125 | # define LDBL_MIN_EXP (-968) |
| 120 | # undef LDBL_MIN_10_EXP | 126 | # undef LDBL_MIN_10_EXP |
| 121 | # define LDBL_MIN_10_EXP DBL_MIN_10_EXP | 127 | # define LDBL_MIN_10_EXP (-291) |
| 122 | # undef LDBL_MIN | 128 | # undef LDBL_MIN |
| 123 | # define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ | 129 | # define LDBL_MIN 0x1p-969L |
| 124 | #endif | 130 | |
| 125 | #if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ | 131 | /* IBM long double is tricky: it is represented as the sum of two doubles, |
| 132 | and the high double must equal the sum of the two parts rounded to nearest. | ||
| 133 | The maximum finite value for which this is true is | ||
| 134 | { 0x1.fffffffffffffp+1023, 0x1.ffffffffffffep+969 }, | ||
| 135 | which represents 0x1.fffffffffffff7ffffffffffff8p+1023L. | ||
| 136 | Although computations can yield representations of numbers larger than this, | ||
| 137 | these computations are considered to have overflowed and behavior is undefined. | ||
| 138 | See <https://gcc.gnu.org/PR120993>. */ | ||
| 126 | # undef LDBL_MAX | 139 | # undef LDBL_MAX |
| 127 | /* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. | 140 | # define LDBL_MAX 0x1.fffffffffffff7ffffffffffff8p+1023L |
| 128 | It is not easy to define: | ||
| 129 | #define LDBL_MAX 1.79769313486231580793728971405302307166e308L | ||
| 130 | is too small, whereas | ||
| 131 | #define LDBL_MAX 1.79769313486231580793728971405302307167e308L | ||
| 132 | is too large. Apparently a bug in GCC decimal-to-binary conversion. | ||
| 133 | Also, I can't get values larger than | ||
| 134 | #define LDBL63 ((long double) (1ULL << 63)) | ||
| 135 | #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 136 | #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 137 | #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 138 | #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) | ||
| 139 | which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. | ||
| 140 | So, define it like this through a reference to an external variable | ||
| 141 | 141 | ||
| 142 | const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; | 142 | /* On PowerPC platforms, 'long double' has a double-double representation. |
| 143 | extern const long double LDBL_MAX; | 143 | Up to ISO C 17, this was outside the scope of ISO C because it can represent |
| 144 | numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits>, such as | ||
| 145 | 1.0L + 4.94065645841246544176568792868221e-324L = 1 + 2^-1074; see | ||
| 146 | ISO C 17 § 5.2.4.2.2.(3). | ||
| 147 | In ISO C 23, wording has been included that makes this 'long double' | ||
| 148 | representation compliant; see ISO C 23 § 5.2.5.3.3.(8)-(9). In this setting, | ||
| 149 | numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits> are | ||
| 150 | called "unnormalized". And since LDBL_EPSILON must be normalized (per | ||
| 151 | ISO C 23 § 5.2.5.3.3.(33)), it must be 2^-105. */ | ||
| 152 | # undef LDBL_EPSILON | ||
| 153 | # define LDBL_EPSILON 0x1p-105L | ||
| 154 | #endif | ||
| 144 | 155 | ||
| 145 | or through a pointer cast | 156 | /* ============================ ISO C11 support ============================ */ |
| 146 | 157 | ||
| 147 | #define LDBL_MAX \ | 158 | /* 'float' properties */ |
| 148 | (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) | ||
| 149 | 159 | ||
| 150 | Unfortunately, this is not a constant expression, and the latter expression | 160 | #ifndef FLT_HAS_SUBNORM |
| 151 | does not work well when GCC is optimizing.. */ | 161 | # define FLT_HAS_SUBNORM 1 |
| 152 | # if !GNULIB_defined_long_double_union | 162 | #endif |
| 153 | union gl_long_double_union | 163 | #ifndef FLT_DECIMAL_DIG |
| 154 | { | 164 | /* FLT_MANT_DIG = 24 => FLT_DECIMAL_DIG = 9 */ |
| 155 | struct { double hi; double lo; } dd; | 165 | # define FLT_DECIMAL_DIG ((int)(FLT_MANT_DIG * 0.3010299956639812 + 2)) |
| 156 | long double ld; | 166 | #endif |
| 157 | }; | 167 | #if defined _AIX && !defined __GNUC__ |
| 158 | # define GNULIB_defined_long_double_union 1 | 168 | /* On AIX, the value of FLT_TRUE_MIN in /usr/include/float.h is a 'double', |
| 169 | not a 'float'. */ | ||
| 170 | # undef FLT_TRUE_MIN | ||
| 171 | #endif | ||
| 172 | #ifndef FLT_TRUE_MIN | ||
| 173 | /* FLT_MIN / 2^(FLT_MANT_DIG-1) */ | ||
| 174 | # define FLT_TRUE_MIN (FLT_MIN / 8388608.0f) | ||
| 175 | #endif | ||
| 176 | |||
| 177 | /* 'double' properties */ | ||
| 178 | |||
| 179 | #ifndef DBL_HAS_SUBNORM | ||
| 180 | # define DBL_HAS_SUBNORM 1 | ||
| 181 | #endif | ||
| 182 | #ifndef DBL_DECIMAL_DIG | ||
| 183 | /* DBL_MANT_DIG = 53 => DBL_DECIMAL_DIG = 17 */ | ||
| 184 | # define DBL_DECIMAL_DIG ((int)(DBL_MANT_DIG * 0.3010299956639812 + 2)) | ||
| 185 | #endif | ||
| 186 | #ifndef DBL_TRUE_MIN | ||
| 187 | /* DBL_MIN / 2^(DBL_MANT_DIG-1) */ | ||
| 188 | # define DBL_TRUE_MIN (DBL_MIN / 4503599627370496.0) | ||
| 189 | #endif | ||
| 190 | |||
| 191 | /* 'long double' properties */ | ||
| 192 | |||
| 193 | #ifndef LDBL_HAS_SUBNORM | ||
| 194 | # define LDBL_HAS_SUBNORM 1 | ||
| 195 | #endif | ||
| 196 | #ifndef LDBL_DECIMAL_DIG | ||
| 197 | /* LDBL_MANT_DIG = 53 => LDBL_DECIMAL_DIG = 17 */ | ||
| 198 | /* LDBL_MANT_DIG = 64 => LDBL_DECIMAL_DIG = 21 */ | ||
| 199 | /* LDBL_MANT_DIG = 106 => LDBL_DECIMAL_DIG = 33 */ | ||
| 200 | /* LDBL_MANT_DIG = 113 => LDBL_DECIMAL_DIG = 36 */ | ||
| 201 | # define LDBL_DECIMAL_DIG ((int)(LDBL_MANT_DIG * 0.3010299956639812 + 2)) | ||
| 202 | #endif | ||
| 203 | #ifndef LDBL_TRUE_MIN | ||
| 204 | /* LDBL_MIN / 2^(LDBL_MANT_DIG-1) */ | ||
| 205 | # if LDBL_MANT_DIG == 53 | ||
| 206 | # define LDBL_TRUE_MIN (LDBL_MIN / 4503599627370496.0L) | ||
| 207 | # elif LDBL_MANT_DIG == 64 | ||
| 208 | # if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__) | ||
| 209 | /* Work around FreeBSD/x86 problem mentioned above. */ | ||
| 210 | extern const union gl_long_double_union gl_LDBL_TRUE_MIN; | ||
| 211 | # define LDBL_TRUE_MIN (gl_LDBL_TRUE_MIN.ld) | ||
| 212 | # else | ||
| 213 | # define LDBL_TRUE_MIN (LDBL_MIN / 9223372036854775808.0L) | ||
| 214 | # endif | ||
| 215 | # elif LDBL_MANT_DIG == 106 | ||
| 216 | # define LDBL_TRUE_MIN (LDBL_MIN / 40564819207303340847894502572032.0L) | ||
| 217 | # elif LDBL_MANT_DIG == 113 | ||
| 218 | # define LDBL_TRUE_MIN (LDBL_MIN / 5192296858534827628530496329220096.0L) | ||
| 159 | # endif | 219 | # endif |
| 160 | extern const union gl_long_double_union gl_LDBL_MAX; | ||
| 161 | # define LDBL_MAX (gl_LDBL_MAX.ld) | ||
| 162 | #endif | 220 | #endif |
| 163 | 221 | ||
| 164 | /* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. | 222 | /* ============================ ISO C23 support ============================ */ |
| 165 | On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON | 223 | |
| 166 | are wrong. */ | 224 | /* 'float' properties */ |
| 167 | #if defined __sgi && (LDBL_MANT_DIG >= 106) | 225 | |
| 168 | # undef LDBL_MANT_DIG | 226 | #ifndef FLT_IS_IEC_60559 |
| 169 | # define LDBL_MANT_DIG 106 | 227 | # if defined __m68k__ |
| 170 | # if defined __GNUC__ | 228 | # define FLT_IS_IEC_60559 0 |
| 171 | # undef LDBL_MIN_EXP | 229 | # else |
| 172 | # define LDBL_MIN_EXP DBL_MIN_EXP | 230 | # define FLT_IS_IEC_60559 1 |
| 173 | # undef LDBL_MIN_10_EXP | 231 | # endif |
| 174 | # define LDBL_MIN_10_EXP DBL_MIN_10_EXP | 232 | #endif |
| 175 | # undef LDBL_MIN | 233 | #ifndef FLT_NORM_MAX |
| 176 | # define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ | 234 | # define FLT_NORM_MAX FLT_MAX |
| 177 | # undef LDBL_EPSILON | 235 | #endif |
| 178 | # define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ | 236 | #ifndef FLT_SNAN |
| 237 | /* For sh, beware of <https://gcc.gnu.org/PR111814>. */ | ||
| 238 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 239 | # define FLT_SNAN __builtin_nansf ("") | ||
| 240 | # else | ||
| 241 | typedef union { unsigned int word[1]; float value; } gl_FLT_SNAN_t; | ||
| 242 | extern gl_FLT_SNAN_t gl_FLT_SNAN; | ||
| 243 | # define FLT_SNAN (gl_FLT_SNAN.value) | ||
| 244 | # define GNULIB_defined_FLT_SNAN 1 | ||
| 245 | # endif | ||
| 246 | #endif | ||
| 247 | |||
| 248 | /* 'double' properties */ | ||
| 249 | |||
| 250 | #ifndef DBL_IS_IEC_60559 | ||
| 251 | # if defined __m68k__ | ||
| 252 | # define DBL_IS_IEC_60559 0 | ||
| 253 | # else | ||
| 254 | # define DBL_IS_IEC_60559 1 | ||
| 179 | # endif | 255 | # endif |
| 180 | #endif | 256 | #endif |
| 257 | #ifndef DBL_NORM_MAX | ||
| 258 | # define DBL_NORM_MAX DBL_MAX | ||
| 259 | #endif | ||
| 260 | #ifndef DBL_SNAN | ||
| 261 | /* For sh, beware of <https://gcc.gnu.org/PR111814>. */ | ||
| 262 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 263 | # define DBL_SNAN __builtin_nans ("") | ||
| 264 | # else | ||
| 265 | typedef union { unsigned long long word[1]; double value; } gl_DBL_SNAN_t; | ||
| 266 | extern gl_DBL_SNAN_t gl_DBL_SNAN; | ||
| 267 | # define DBL_SNAN (gl_DBL_SNAN.value) | ||
| 268 | # define GNULIB_defined_DBL_SNAN 1 | ||
| 269 | # endif | ||
| 270 | #endif | ||
| 271 | |||
| 272 | /* 'long double' properties */ | ||
| 273 | |||
| 274 | #ifndef LDBL_IS_IEC_60559 | ||
| 275 | # if defined __m68k__ | ||
| 276 | # define LDBL_IS_IEC_60559 0 | ||
| 277 | # elif LDBL_MANT_DIG == 53 || LDBL_MANT_DIG == 113 | ||
| 278 | # define LDBL_IS_IEC_60559 1 | ||
| 279 | # else | ||
| 280 | # define LDBL_IS_IEC_60559 0 | ||
| 281 | # endif | ||
| 282 | #endif | ||
| 283 | #ifndef LDBL_NORM_MAX | ||
| 284 | # ifdef __LDBL_NORM_MAX__ | ||
| 285 | # define LDBL_NORM_MAX __LDBL_NORM_MAX__ | ||
| 286 | # elif FLT_RADIX == 2 && LDBL_MAX_EXP == 1024 && LDBL_MANT_DIG == 106 | ||
| 287 | # define LDBL_NORM_MAX 0x1.ffffffffffffffffffffffffff8p+1022L | ||
| 288 | # else | ||
| 289 | # define LDBL_NORM_MAX LDBL_MAX | ||
| 290 | # endif | ||
| 291 | #endif | ||
| 292 | #ifndef LDBL_SNAN | ||
| 293 | /* For sh, beware of <https://gcc.gnu.org/PR111814>. */ | ||
| 294 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 295 | # define LDBL_SNAN __builtin_nansl ("") | ||
| 296 | # else | ||
| 297 | # if LDBL_MANT_DIG == 53 | ||
| 298 | typedef union { unsigned long long word[1]; long double value; } gl_LDBL_SNAN_t; | ||
| 299 | # elif defined __m68k__ | ||
| 300 | typedef union { unsigned int word[3]; long double value; } gl_LDBL_SNAN_t; | ||
| 301 | # else | ||
| 302 | typedef union { unsigned long long word[2]; long double value; } gl_LDBL_SNAN_t; | ||
| 303 | # endif | ||
| 304 | extern gl_LDBL_SNAN_t gl_LDBL_SNAN; | ||
| 305 | # define LDBL_SNAN (gl_LDBL_SNAN.value) | ||
| 306 | # define GNULIB_defined_LDBL_SNAN 1 | ||
| 307 | # endif | ||
| 308 | #endif | ||
| 309 | |||
| 310 | /* ================================= Other ================================= */ | ||
| 181 | 311 | ||
| 182 | #if @REPLACE_ITOLD@ | 312 | #if @REPLACE_ITOLD@ |
| 183 | /* Pull in a function that fixes the 'int' to 'long double' conversion | 313 | /* Pull in a function that fixes the 'int' to 'long double' conversion |
