Home | History | Annotate | Download | only in lib
      1 /* Emulation for ldexpl.
      2    Contributed by Paolo Bonzini
      3 
      4    Copyright 2002-2003, 2007-2012 Free Software Foundation, Inc.
      5 
      6    This file is part of gnulib.
      7 
      8    This program is free software: you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20 
     21 #include <config.h>
     22 
     23 /* Specification.  */
     24 #include <math.h>
     25 
     26 #if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
     27 
     28 long double
     29 ldexpl (long double x, int exp)
     30 {
     31   return ldexp (x, exp);
     32 }
     33 
     34 #else
     35 
     36 # include <float.h>
     37 # include "fpucw.h"
     38 
     39 long double
     40 ldexpl (long double x, int exp)
     41 {
     42   long double factor;
     43   int bit;
     44   DECL_LONG_DOUBLE_ROUNDING
     45 
     46   BEGIN_LONG_DOUBLE_ROUNDING ();
     47 
     48   /* Check for zero, nan and infinity. */
     49   if (!(isnanl (x) || x + x == x))
     50     {
     51       if (exp < 0)
     52         {
     53           exp = -exp;
     54           factor = 0.5L;
     55         }
     56       else
     57         factor = 2.0L;
     58 
     59       if (exp > 0)
     60         for (bit = 1;;)
     61           {
     62             /* Invariant: Here bit = 2^i, factor = 2^-2^i or = 2^2^i,
     63                and bit <= exp.  */
     64             if (exp & bit)
     65               x *= factor;
     66             bit <<= 1;
     67             if (bit > exp)
     68               break;
     69             factor = factor * factor;
     70           }
     71     }
     72 
     73   END_LONG_DOUBLE_ROUNDING ();
     74 
     75   return x;
     76 }
     77 
     78 #endif
     79 
     80 #if 0
     81 int
     82 main (void)
     83 {
     84   long double x;
     85   int y;
     86   for (y = 0; y < 29; y++)
     87     printf ("%5d %.16Lg %.16Lg\n", y, ldexpl (0.8L, y), ldexpl (0.8L, -y) * ldexpl (0.8L, y));
     88 }
     89 #endif
     90