* lib/ldexpl.c (ldexpl): Use an 'unsigned int' variable to represent the
absolute value of exp without overflow.
+2023-08-19 Bruno Haible <bruno@clisp.org>
+
+ ldexpl: Fix signed integer overflow.
+ * lib/ldexpl.c (ldexpl): Use an 'unsigned int' variable to represent the
+ absolute value of exp without overflow.
+
2023-08-19 Bruno Haible <bruno@clisp.org>
logbl: Work around endless loop on OpenBSD 7.3/mips64.
long double
ldexpl (long double x, int exp)
{
+ unsigned int uexp;
long double factor;
- int bit;
+ unsigned int bit;
DECL_LONG_DOUBLE_ROUNDING
BEGIN_LONG_DOUBLE_ROUNDING ();
{
if (exp < 0)
{
- exp = -exp;
+ /* Avoid signed integer overflow when exp == INT_MIN. */
+ uexp = (unsigned int) (-1 - exp) + 1;
factor = 0.5L;
}
else
- factor = 2.0L;
+ {
+ uexp = exp;
+ factor = 2.0L;
+ }
- if (exp > 0)
+ if (uexp > 0)
for (bit = 1;;)
{
/* Invariant: Here bit = 2^i, factor = 2^-2^i or = 2^2^i,
- and bit <= exp. */
- if (exp & bit)
+ and bit <= uexp. */
+ if (uexp & bit)
x *= factor;
bit <<= 1;
- if (bit > exp)
+ if (bit == 0 || bit > uexp)
break;
factor = factor * factor;
}