From b0afb8fe0ff1d87165af9df61501197a06240dda Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 28 Dec 2025 12:13:40 +0100 Subject: Sync with Gnulib stable-202507 code (a8ac9f9ce5) --- gl/float.in.h | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 194 insertions(+), 27 deletions(-) (limited to 'gl/float.in.h') diff --git a/gl/float.in.h b/gl/float.in.h index 73e8d406..d75a06e7 100644 --- a/gl/float.in.h +++ b/gl/float.in.h @@ -1,6 +1,6 @@ /* A correct . - 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 @@ -28,6 +28,8 @@ #ifndef _@GUARD_PREFIX@_FLOAT_H #define _@GUARD_PREFIX@_FLOAT_H +/* ============================ ISO C99 support ============================ */ + /* 'long double' properties. */ #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) @@ -111,44 +113,38 @@ extern const union gl_long_double_union gl_LDBL_MAX; # define LDBL_MAX_10_EXP 4932 #endif -/* 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 PowerPC with gcc 15 when using __ibm128 long double, the value of + LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX, and LDBL_NORM_MAX are wrong. */ +#if (defined _ARCH_PPC && LDBL_MANT_DIG == 106 \ + && 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 */ -#endif -#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ # 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 +/* LDBL_MAX is 2**1024 - 2**918, represented as: { 0x7FEFFFFF, 0xFFFFFFFF, + 0x7C9FFFFF, 0xFFFFFFFF }. + + Do not write it as a constant expression, as GCC would likely treat + that as infinity due to the vagaries of this platform's funky arithmetic. + Instead, define it through a reference to an external variable. + Like the following, but using a union to avoid type mismatches: - const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; + const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / 0x1p53 }; extern const long double LDBL_MAX; - or through a pointer cast + The following alternative would not work as well when GCC is optimizing: - #define LDBL_MAX \ - (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) + #define LDBL_MAX (*(long double const *) (double[]) + { DBL_MAX, DBL_MAX / 0x1p53 }) - Unfortunately, this is not a constant expression, and the latter expression - does not work well when GCC is optimizing.. */ + The following alternative would require GCC 6 or later: + + #define LDBL_MAX __builtin_pack_longdouble (DBL_MAX, DBL_MAX / 0x1p53) + + Unfortunately none of the alternatives are constant expressions. */ # if !GNULIB_defined_long_double_union union gl_long_double_union { @@ -159,6 +155,8 @@ union gl_long_double_union # endif extern const union gl_long_double_union gl_LDBL_MAX; # define LDBL_MAX (gl_LDBL_MAX.ld) +# undef LDBL_NORM_MAX +# define LDBL_NORM_MAX LDBL_MAX #endif /* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. @@ -179,6 +177,175 @@ extern const union gl_long_double_union gl_LDBL_MAX; # endif #endif +/* 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><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><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. */ +#if defined __powerpc__ && LDBL_MANT_DIG == 106 +# undef LDBL_EPSILON +# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ +#endif + +/* ============================ ISO C11 support ============================ */ + +/* 'float' properties */ + +#ifndef FLT_HAS_SUBNORM +# define FLT_HAS_SUBNORM 1 +#endif +#ifndef FLT_DECIMAL_DIG +/* FLT_MANT_DIG = 24 => FLT_DECIMAL_DIG = 9 */ +# define FLT_DECIMAL_DIG ((int)(FLT_MANT_DIG * 0.3010299956639812 + 2)) +#endif +#if defined _AIX && !defined __GNUC__ +/* On AIX, the value of FLT_TRUE_MIN in /usr/include/float.h is a 'double', + not a 'float'. */ +# undef FLT_TRUE_MIN +#endif +#ifndef FLT_TRUE_MIN +/* FLT_MIN / 2^(FLT_MANT_DIG-1) */ +# define FLT_TRUE_MIN (FLT_MIN / 8388608.0f) +#endif + +/* 'double' properties */ + +#ifndef DBL_HAS_SUBNORM +# define DBL_HAS_SUBNORM 1 +#endif +#ifndef DBL_DECIMAL_DIG +/* DBL_MANT_DIG = 53 => DBL_DECIMAL_DIG = 17 */ +# define DBL_DECIMAL_DIG ((int)(DBL_MANT_DIG * 0.3010299956639812 + 2)) +#endif +#ifndef DBL_TRUE_MIN +/* DBL_MIN / 2^(DBL_MANT_DIG-1) */ +# define DBL_TRUE_MIN (DBL_MIN / 4503599627370496.0) +#endif + +/* 'long double' properties */ + +#ifndef LDBL_HAS_SUBNORM +# define LDBL_HAS_SUBNORM 1 +#endif +#ifndef LDBL_DECIMAL_DIG +/* LDBL_MANT_DIG = 53 => LDBL_DECIMAL_DIG = 17 */ +/* LDBL_MANT_DIG = 64 => LDBL_DECIMAL_DIG = 21 */ +/* LDBL_MANT_DIG = 106 => LDBL_DECIMAL_DIG = 33 */ +/* LDBL_MANT_DIG = 113 => LDBL_DECIMAL_DIG = 36 */ +# define LDBL_DECIMAL_DIG ((int)(LDBL_MANT_DIG * 0.3010299956639812 + 2)) +#endif +#ifndef LDBL_TRUE_MIN +/* LDBL_MIN / 2^(LDBL_MANT_DIG-1) */ +# if LDBL_MANT_DIG == 53 +# define LDBL_TRUE_MIN (LDBL_MIN / 4503599627370496.0L) +# elif LDBL_MANT_DIG == 64 +# if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__) +/* Work around FreeBSD/x86 problem mentioned above. */ +extern const union gl_long_double_union gl_LDBL_TRUE_MIN; +# define LDBL_TRUE_MIN (gl_LDBL_TRUE_MIN.ld) +# else +# define LDBL_TRUE_MIN (LDBL_MIN / 9223372036854775808.0L) +# endif +# elif LDBL_MANT_DIG == 106 +# define LDBL_TRUE_MIN (LDBL_MIN / 40564819207303340847894502572032.0L) +# elif LDBL_MANT_DIG == 113 +# define LDBL_TRUE_MIN (LDBL_MIN / 5192296858534827628530496329220096.0L) +# endif +#endif + +/* ============================ ISO C23 support ============================ */ + +/* 'float' properties */ + +#ifndef FLT_IS_IEC_60559 +# if defined __m68k__ +# define FLT_IS_IEC_60559 0 +# else +# define FLT_IS_IEC_60559 1 +# endif +#endif +#ifndef FLT_NORM_MAX +# define FLT_NORM_MAX FLT_MAX +#endif +#ifndef FLT_SNAN +/* For sh, beware of . */ +# if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ +# define FLT_SNAN __builtin_nansf ("") +# else +typedef union { unsigned int word[1]; float value; } gl_FLT_SNAN_t; +extern gl_FLT_SNAN_t gl_FLT_SNAN; +# define FLT_SNAN (gl_FLT_SNAN.value) +# define GNULIB_defined_FLT_SNAN 1 +# endif +#endif + +/* 'double' properties */ + +#ifndef DBL_IS_IEC_60559 +# if defined __m68k__ +# define DBL_IS_IEC_60559 0 +# else +# define DBL_IS_IEC_60559 1 +# endif +#endif +#ifndef DBL_NORM_MAX +# define DBL_NORM_MAX DBL_MAX +#endif +#ifndef DBL_SNAN +/* For sh, beware of . */ +# if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ +# define DBL_SNAN __builtin_nans ("") +# else +typedef union { unsigned long long word[1]; double value; } gl_DBL_SNAN_t; +extern gl_DBL_SNAN_t gl_DBL_SNAN; +# define DBL_SNAN (gl_DBL_SNAN.value) +# define GNULIB_defined_DBL_SNAN 1 +# endif +#endif + +/* 'long double' properties */ + +#ifndef LDBL_IS_IEC_60559 +# if defined __m68k__ +# define LDBL_IS_IEC_60559 0 +# elif LDBL_MANT_DIG == 53 || LDBL_MANT_DIG == 113 +# define LDBL_IS_IEC_60559 1 +# else +# define LDBL_IS_IEC_60559 0 +# endif +#endif +#ifndef LDBL_NORM_MAX +# ifdef __LDBL_NORM_MAX__ +# define LDBL_NORM_MAX __LDBL_NORM_MAX__ +# else +# define LDBL_NORM_MAX LDBL_MAX +# endif +#endif +#ifndef LDBL_SNAN +/* For sh, beware of . */ +# if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ +# define LDBL_SNAN __builtin_nansl ("") +# else +# if LDBL_MANT_DIG == 53 +typedef union { unsigned long long word[1]; long double value; } gl_LDBL_SNAN_t; +# elif defined __m68k__ +typedef union { unsigned int word[3]; long double value; } gl_LDBL_SNAN_t; +# else +typedef union { unsigned long long word[2]; long double value; } gl_LDBL_SNAN_t; +# endif +extern gl_LDBL_SNAN_t gl_LDBL_SNAN; +# define LDBL_SNAN (gl_LDBL_SNAN.value) +# define GNULIB_defined_LDBL_SNAN 1 +# endif +#endif + +/* ================================= Other ================================= */ + #if @REPLACE_ITOLD@ /* Pull in a function that fixes the 'int' to 'long double' conversion of glibc 2.7. */ -- cgit v1.2.3-74-g34f1