~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to src/gmp/mpz/get_d.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2007-04-09 11:51:51 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070409115151-ql8cr0kalzx1jmla
Tags: 0.9i-20070324-2
Upload to unstable. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* double mpz_get_d (mpz_t src) -- Return the double approximation to SRC.
2
2
 
3
 
Copyright 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
 
3
Copyright 1996, 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4
4
 
5
5
This file is part of the GNU MP Library.
6
6
 
16
16
 
17
17
You should have received a copy of the GNU Lesser General Public License
18
18
along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19
 
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
 
MA 02111-1307, USA. */
 
19
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
20
MA 02110-1301, USA. */
21
21
 
22
22
#include "gmp.h"
23
23
#include "gmp-impl.h"
24
 
#include "longlong.h"
25
 
 
26
 
 
27
 
/* FIXME: Would prefer to inline this on all compilers, not just those with
28
 
   "inline".  */
29
 
static inline int
30
 
mpn_zero_p (mp_srcptr p, mp_size_t n)
31
 
{
32
 
  mp_size_t i;
33
 
 
34
 
  for (i = 0; i < n; i++)
35
 
    if (p[i] != 0)
36
 
      return 0;
37
 
 
38
 
  return 1;
39
 
}
40
 
 
41
24
 
42
25
double
43
 
mpz_get_d (mpz_srcptr src)
 
26
mpz_get_d (mpz_srcptr z)
44
27
{
45
 
  double res;
46
28
  mp_size_t size;
47
 
  int negative;
48
 
  mp_ptr qp;
49
 
  mp_limb_t hz, lz;
50
 
  int cnt;
51
29
 
52
 
  size = SIZ(src);
53
 
  if (size == 0)
 
30
  size = SIZ (z);
 
31
  if (UNLIKELY (size == 0))
54
32
    return 0.0;
55
33
 
56
 
  negative = size < 0;
57
 
  size = ABS (size);
58
 
  qp = PTR(src);
59
 
 
60
 
  if (size == 1)
61
 
    {
62
 
      res = qp[size - 1];
63
 
    }
64
 
  else if (size == 2)
65
 
    {
66
 
      res = MP_BASE_AS_DOUBLE * qp[size - 1] + qp[size - 2];
67
 
    }
68
 
  else
69
 
    {
70
 
      count_leading_zeros (cnt, qp[size - 1]);
71
 
      cnt -= GMP_NAIL_BITS;
72
 
 
73
 
#if BITS_PER_MP_LIMB == 32
74
 
      if (cnt == 0)
75
 
        {
76
 
          hz = qp[size - 1];
77
 
          lz = qp[size - 2];
78
 
        }
79
 
      else
80
 
        {
81
 
          hz = ((qp[size - 1] << cnt) | (qp[size - 2] >> GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK;
82
 
          lz = ((qp[size - 2] << cnt) | (qp[size - 3] >> GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK;
83
 
        }
84
 
#if _GMP_IEEE_FLOATS
85
 
      /* Take bits from less significant limbs, but only if they may affect
86
 
         the result.  */
87
 
      if ((lz & 0x7ff) == 0x400)
88
 
        {
89
 
          if (cnt != 0)
90
 
            lz += (((qp[size - 3] << cnt) & GMP_NUMB_MASK) != 0
91
 
                   || ! mpn_zero_p (qp, size - 3));
92
 
          else
93
 
            lz += (! mpn_zero_p (qp, size - 2));
94
 
        }
95
 
#endif
96
 
      res = MP_BASE_AS_DOUBLE * hz + lz;
97
 
      res = __gmp_scale2 (res, (size - 2) * GMP_NUMB_BITS - cnt);
98
 
#endif
99
 
#if BITS_PER_MP_LIMB == 64
100
 
      if (cnt == 0)
101
 
        hz = qp[size - 1];
102
 
      else
103
 
        hz = ((qp[size - 1] << cnt) | (qp[size - 2] >> GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK;
104
 
#if _GMP_IEEE_FLOATS
105
 
      if ((hz & 0x7ff) == 0x400)
106
 
        {
107
 
          if (cnt != 0)
108
 
            hz += (((qp[size - 2] << cnt) & GMP_NUMB_MASK) != 0
109
 
                   || ! mpn_zero_p (qp, size - 2));
110
 
          else
111
 
            hz += (! mpn_zero_p (qp, size - 1));
112
 
        }
113
 
#endif
114
 
      res = hz;
115
 
      res = __gmp_scale2 (res, (size - 1) * GMP_NUMB_BITS - cnt);
116
 
#endif
117
 
    }
118
 
 
119
 
  return negative ? -res : res;
 
34
  return mpn_get_d (PTR (z), ABS (size), size, 0L);
120
35
}