a4cdae19eff22b6e2520f01b1c93f91dcdc6388a
[gnulib.git] / lib / ldexpl.c
1 /* Emulation for ldexpl.
2    Contributed by Paolo Bonzini
3
4    Copyright 2002, 2003 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 2, or (at your option)
11    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 along
19    with this program; if not, write to the Free Software Foundation,
20    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22 #include <float.h>
23 #include <math.h>
24
25 #include "mathl.h"
26
27 long double
28 ldexpl(long double x, int exp)
29 {
30   long double factor;
31   int bit;
32
33   /* Check for zero, nan and infinity. */
34   if (x != x || x + x == x )
35     return x;
36
37   if (exp < 0)
38     {
39       exp = -exp;
40       factor = 0.5L;
41     }
42   else
43     factor = 2.0L;
44
45   for (bit = 1; bit <= exp; bit <<= 1, factor *= factor)
46     if (exp & bit)
47       x *= factor;
48
49   return x;
50 }
51
52 #if 0
53 int
54 main (void)
55 {
56   long double x;
57   int y;
58   for (y = 0; y < 29; y++)
59     printf ("%5d %.16Lg %.16Lg\n", y, ldexpl(0.8L, y), ldexpl(0.8L, -y) * ldexpl(0.8L, y));
60 }
61 #endif