From 9a18258bbd90815fea0eeabea8e363de469464b4 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 30 Mar 2007 00:19:34 +0000 Subject: [PATCH] Set the FPU control word as needed for 'long double' computations. --- ChangeLog | 7 +++++++ lib/ldexpl.c | 37 ++++++++++++++++++++++++++----------- modules/ldexpl | 1 + 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c42d3bbe..70487b307 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2007-03-29 Bruno Haible + * lib/ldexpl.c: Include fpucw.h. + (ldexpl): Use BEGIN/END_LONG_DOUBLE_ROUNDING. Skip the last unneeded + multiplication. + * modules/ldexpl (Depends-on): Add fpucw. + +2007-03-29 Bruno Haible + * modules/ldexpl: New file. * m4/ldexpl.m4: New file. * lib/math_.h (ldexpl): Define to a replacement if REPLACE_LDEXPL is diff --git a/lib/ldexpl.c b/lib/ldexpl.c index f85847b24..bb16be66b 100644 --- a/lib/ldexpl.c +++ b/lib/ldexpl.c @@ -25,6 +25,7 @@ #include #include +#include "fpucw.h" #include "isnanl.h" long double @@ -32,22 +33,36 @@ ldexpl(long double x, int exp) { long double factor; int bit; + DECL_LONG_DOUBLE_ROUNDING - /* Check for zero, nan and infinity. */ - if (isnanl (x) || x + x == x) - return x; + BEGIN_LONG_DOUBLE_ROUNDING (); - if (exp < 0) + /* Check for zero, nan and infinity. */ + if (!(isnanl (x) || x + x == x)) { - exp = -exp; - factor = 0.5L; + if (exp < 0) + { + exp = -exp; + factor = 0.5L; + } + else + factor = 2.0L; + + if (exp > 0) + for (bit = 1;;) + { + /* Invariant: Here bit = 2^i, factor = 2^-2^i or = 2^2^i, + and bit <= exp. */ + if (exp & bit) + x *= factor; + bit <<= 1; + if (bit > exp) + break; + factor = factor * factor; + } } - else - factor = 2.0L; - for (bit = 1; bit <= exp; bit <<= 1, factor *= factor) - if (exp & bit) - x *= factor; + END_LONG_DOUBLE_ROUNDING (); return x; } diff --git a/modules/ldexpl b/modules/ldexpl index c89187a50..1d759d02b 100644 --- a/modules/ldexpl +++ b/modules/ldexpl @@ -8,6 +8,7 @@ m4/ldexpl.m4 Depends-on: math isnanl-nolibm +fpucw configure.ac: gl_FUNC_LDEXPL -- 2.11.0