diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2025-10-18 19:06:52 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2025-10-18 19:06:52 +0200 |
commit | 27dae84ed92f1ef0300263091972338d12e78348 (patch) | |
tree | 7c52931f474fafb8a4bd4fd15ca3461c77cdecc2 /lib/float.in.h | |
parent | 4682deeb62247d34de87f8e777f99e2d337fd377 (diff) |
New upstream version 1.4.1upstream/1.4.1upstream
Diffstat (limited to 'lib/float.in.h')
-rw-r--r-- | lib/float.in.h | 108 |
1 files changed, 43 insertions, 65 deletions
diff --git a/lib/float.in.h b/lib/float.in.h index 5e78b4f2..3093f9a0 100644 --- a/lib/float.in.h +++ b/lib/float.in.h @@ -1,6 +1,6 @@ /* A correct <float.h>. - Copyright (C) 2007-2024 Free Software Foundation, Inc. + Copyright (C) 2007-2025 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -115,70 +115,42 @@ extern const union gl_long_double_union gl_LDBL_MAX; /* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are wrong. - On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ -#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ + On Linux/PowerPC with gcc 8.3, the values of LDBL_MAX and LDBL_EPSILON are + wrong. + Assume these bugs are fixed in any GCC new enough + to define __LDBL_NORM_MAX__. */ +#if (defined __powerpc__ && LDBL_MANT_DIG == 106 \ + && defined __GNUC__ && !defined __LDBL_NORM_MAX__) # undef LDBL_MIN_EXP -# define LDBL_MIN_EXP DBL_MIN_EXP +# define LDBL_MIN_EXP (-968) # undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP DBL_MIN_10_EXP +# define LDBL_MIN_10_EXP (-291) # undef LDBL_MIN -# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ -#endif -#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ +# define LDBL_MIN 0x1p-969L + +/* IBM long double is tricky: it is represented as the sum of two doubles, + and the high double must equal the sum of the two parts rounded to nearest. + The maximum finite value for which this is true is + { 0x1.fffffffffffffp+1023, 0x1.ffffffffffffep+969 }, + which represents 0x1.fffffffffffff7ffffffffffff8p+1023L. + Although computations can yield representations of numbers larger than this, + these computations are considered to have overflowed and behavior is undefined. + See <https://gcc.gnu.org/PR120993>. */ # undef LDBL_MAX -/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. - It is not easy to define: - #define LDBL_MAX 1.79769313486231580793728971405302307166e308L - is too small, whereas - #define LDBL_MAX 1.79769313486231580793728971405302307167e308L - is too large. Apparently a bug in GCC decimal-to-binary conversion. - Also, I can't get values larger than - #define LDBL63 ((long double) (1ULL << 63)) - #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) - which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. - So, define it like this through a reference to an external variable - - const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; - extern const long double LDBL_MAX; - - or through a pointer cast - - #define LDBL_MAX \ - (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) - - Unfortunately, this is not a constant expression, and the latter expression - does not work well when GCC is optimizing.. */ -# if !GNULIB_defined_long_double_union -union gl_long_double_union - { - struct { double hi; double lo; } dd; - long double ld; - }; -# define GNULIB_defined_long_double_union 1 -# endif -extern const union gl_long_double_union gl_LDBL_MAX; -# define LDBL_MAX (gl_LDBL_MAX.ld) -#endif - -/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. - On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON - are wrong. */ -#if defined __sgi && (LDBL_MANT_DIG >= 106) -# undef LDBL_MANT_DIG -# define LDBL_MANT_DIG 106 -# if defined __GNUC__ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP DBL_MIN_EXP -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP DBL_MIN_10_EXP -# undef LDBL_MIN -# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ -# undef LDBL_EPSILON -# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ -# endif +# define LDBL_MAX 0x1.fffffffffffff7ffffffffffff8p+1023L + +/* On PowerPC platforms, 'long double' has a double-double representation. + Up to ISO C 17, this was outside the scope of ISO C because it can represent + numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits>, such as + 1.0L + 4.94065645841246544176568792868221e-324L = 1 + 2^-1074; see + ISO C 17 § 5.2.4.2.2.(3). + In ISO C 23, wording has been included that makes this 'long double' + representation compliant; see ISO C 23 § 5.2.5.3.3.(8)-(9). In this setting, + numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits> are + called "unnormalized". And since LDBL_EPSILON must be normalized (per + ISO C 23 § 5.2.5.3.3.(33)), it must be 2^-105. */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 0x1p-105L #endif /* ============================ ISO C11 support ============================ */ @@ -262,7 +234,7 @@ extern const union gl_long_double_union gl_LDBL_TRUE_MIN; # define FLT_NORM_MAX FLT_MAX #endif #ifndef FLT_SNAN -/* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ +/* For sh, beware of <https://gcc.gnu.org/PR111814>. */ # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ # define FLT_SNAN __builtin_nansf ("") # else @@ -286,7 +258,7 @@ extern gl_FLT_SNAN_t gl_FLT_SNAN; # define DBL_NORM_MAX DBL_MAX #endif #ifndef DBL_SNAN -/* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ +/* For sh, beware of <https://gcc.gnu.org/PR111814>. */ # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ # define DBL_SNAN __builtin_nans ("") # else @@ -309,10 +281,16 @@ extern gl_DBL_SNAN_t gl_DBL_SNAN; # endif #endif #ifndef LDBL_NORM_MAX -# define LDBL_NORM_MAX LDBL_MAX +# ifdef __LDBL_NORM_MAX__ +# define LDBL_NORM_MAX __LDBL_NORM_MAX__ +# elif FLT_RADIX == 2 && LDBL_MAX_EXP == 1024 && LDBL_MANT_DIG == 106 +# define LDBL_NORM_MAX 0x1.ffffffffffffffffffffffffff8p+1022L +# else +# define LDBL_NORM_MAX LDBL_MAX +# endif #endif #ifndef LDBL_SNAN -/* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ +/* For sh, beware of <https://gcc.gnu.org/PR111814>. */ # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ # define LDBL_SNAN __builtin_nansl ("") # else |