source: git/MP/MP/MP_GmpBigReal.c @ 4439165

spielwiese
Last change on this file since 4439165 was 4439165, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: gcc 4.3 git-svn-id: file:///usr/local/Singular/svn/trunk@11873 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*******************************************************************
2 *   IMPLEMENTATION FILE:  MP_GmpBigNum.c
3 *
4 *      The default BigInt and BigReal package is the Gnu Multiple 
5 *      Precision package (see root directory for MP for licensing
6 *      details).  Here we have the routines to put/get/print a GMP 
7 *      big float.
8 *
9 *  Change Log:
10 *      3/97 obachman Life begins for this file.
11 ************************************************************************/
12
13#include "MP.h"
14#include <string.h>
15
16#ifdef MP_HAVE_GMP_APREAL
17
18#ifdef  __GNU_MP_VERSION
19#if  __GNU_MP_VERSION > 2
20#define _mp_allocate_func      __gmp_allocate_func
21#define _mp_reallocate_func    __gmp_reallocate_func
22#define _mp_free_func          __gmp_free_func
23#endif
24#endif
25
26EXTERN void* (*_mp_allocate_func) (size_t size);
27EXTERN void (*_mp_free_func) (void* ptr, size_t size);
28
29MP_BigRealOps_t imp_gmp_bigreal_ops = {
30    IMP_PutGmpReal,
31    IMP_GetGmpReal,
32    IMP_GmpRealToStr,
33    IMP_GmpRealAsciiSize
34};
35
36#if MP_DEFAULT_APREAL_FORMAT == MP_GMP
37MP_BigRealOps_t imp_default_bigreal_ops =
38{
39    IMP_PutGmpReal,
40    IMP_GetGmpReal,
41    IMP_GmpRealToStr,
42    IMP_GmpRealAsciiSize
43};
44MP_BigNumFormat_t imp_default_bigreal_format = MP_GMP;
45#endif
46
47
48#ifdef __STDC__
49MP_Status_t IMP_PutGmpReal(MP_Link_pt link, MP_ApReal_t mp_apreal)
50#else
51MP_Status_t IMP_PutGmpReal(link, apreal)
52    MP_Link_pt link;
53     MP_ApReal_t  apreal;
54#endif
55{
56    mpf_ptr apreal = (mpf_ptr) mp_apreal;
57
58#ifdef MP_DEBUG
59    fprintf(stderr, "IMP_PutGmpReal: entering\n");
60    fflush(stderr);
61#endif
62
63    if (!IMP_PutLong(link, (long *)&(apreal->_mp_prec)))
64        return MP_SetError(link, MP_CantPutDataPacket);
65
66    if (!IMP_PutLong(link, (long *)&(apreal->_mp_size)))
67        return MP_SetError(link, MP_CantPutDataPacket);
68
69    if (!IMP_PutLong(link, (long *)&(apreal->_mp_exp)))
70        return MP_SetError(link, MP_CantPutDataPacket);
71
72    if (apreal->_mp_size != 0)
73      return IMP_PutUint32Vector(link, apreal->_mp_d,
74                                 (apreal->_mp_size < 0 ?
75                                  - apreal->_mp_size : apreal->_mp_size));
76    else
77      return MP_ClearError(link);
78}
79
80
81
82#ifdef __STDC__
83MP_Status_t IMP_GetGmpReal(MP_Link_pt link, MP_ApReal_t *mp_apreal)
84#else
85MP_Status_t IMP_GetGmpReal(link, apreal)
86    MP_Link_pt link;
87    MP_ApReal_t *mp_apreal;
88#endif
89{
90    long int  n;
91    mpf_ptr apreal;
92   
93#ifdef MP_DEBUG
94    fprintf(stderr, "IMP_GetGmpReal: entering\n");
95    fflush(stderr);
96#endif
97    if (*mp_apreal == NULL)
98    {
99      *mp_apreal = (MP_ApReal_t) IMP_MemAllocFnc(sizeof(*apreal));
100      apreal = (mpf_ptr) *mp_apreal;
101      mpf_init(apreal);
102    }
103    else
104    {
105      apreal = (mpf_ptr) *mp_apreal;
106      mpf_clear(apreal);  /* start with a clean structure */
107    }
108
109    if (!IMP_GetLong(link, (long *)&(apreal->_mp_prec)))
110        return MP_SetError(link, MP_CantGetDataPacket);
111
112    if (!IMP_GetLong(link, (long *)&(apreal->_mp_size)))
113        return MP_SetError(link, MP_CantGetDataPacket);
114
115    if (!IMP_GetLong(link, &(apreal->_mp_exp)))
116        return MP_SetError(link, MP_CantGetDataPacket);
117
118    n = (apreal->_mp_size < 0 ? (- apreal->_mp_size) : apreal->_mp_size);
119
120    apreal->_mp_d = (mp_ptr)(*_mp_allocate_func)((apreal->_mp_prec + 1) *
121                                                 (mp_bits_per_limb/8));
122    if (n > 0)
123      return IMP_GetUint32Vector(link, &(apreal->_mp_d), n);
124    else
125      return MP_ClearError(link);
126}
127
128#ifdef __STDC__
129char * IMP_GmpRealToStr(MP_ApReal_t mp_apreal, char *buffer)
130#else
131char * IMP_GmpRealToStr(link, apreal, buffer)
132    MP_Link_pt link;
133    MP_ApReal_t mp_apreal;
134    char *buffer;
135#endif
136{
137  mpf_ptr apreal = (mpf_ptr) mp_apreal;
138  char     *str = NULL;
139  long     len = 0;
140  mp_exp_t exp;
141
142#ifdef MP_DEBUG
143  fprintf(stderr, "IMP_GmpRealToStr: entering\n");
144  fflush(stderr);
145#endif
146
147  str = mpf_get_str(NULL, &exp, 10, 0, apreal);
148  /* 3.14 is printed as 314 with exp == 1; Hence we need to add one to
149     exp for 0.314 */
150  sprintf(buffer, "0.%s@%ld", str, exp + 1);
151  _mp_free_func(str, strlen(str) + 1);
152
153  return buffer;
154}
155
156long IMP_GmpRealAsciiSize(MP_ApReal_t mp_apreal)
157{
158  mpf_ptr apreal = (mpf_ptr) mp_apreal;
159  char     *str = NULL;
160  mp_exp_t exp;
161  long len;
162 
163  /* not the most efficient way to find out the length -- but the only
164     possible one, provided we use n_digit == 0 */
165  str = mpf_get_str(NULL, &exp, 10, 0, apreal);
166  len = strlen(str);
167  _mp_free_func(str, len + 1);
168
169  /*
170   * the 15 is for the "0.", the "@" and the exponent that will
171   * appear in the final result.  This allows 12 digits for the
172   * exponent - hope this is enough.
173   */
174
175  return len + 15;
176
177}
178
179
180#endif /* MP_HAVE_GMP_APREAL */
Note: See TracBrowser for help on using the repository browser.