source: git/MP/MP/MP_PariBigInt.c @ 224da5b

fieker-DuValspielwiese
Last change on this file since 224da5b was 71b3e0, checked in by Olaf Bachmann <obachman@…>, 26 years ago
1998-10-14 Olaf Bachmann <obachman@mathematik.uni-kl.de> * MP_PariBigInt.[c,h]: Added memory management functions for Pari Bigints * MPT_ApNumber.c: MPT_DeleteApInt, MPT_InitCpyApInt is determined w.r.t. MP_DEFAULT_APINT_FORMAT and extended to MP_DEFAULT_APINT_FORMAT == MP_PARI git-svn-id: file:///usr/local/Singular/svn/trunk@2566 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/****************************************************************
2 *                                                                 
3 * FILE:     MP_PariBigInt.c
4 * Authors:  O. Bachmann, T. Metzner, H. Schoenemann, A. Sorgatz
5 * Date:     February 97
6 *                                                               
7 ***************************************************************/
8
9
10#include "MP.h"
11
12#ifdef MP_HAVE_PARI
13/* used to dynamically set the bigint ops to the ones defined here */
14MP_BigIntOps_t imp_pari_bigint_ops = {
15  IMP_PutPariBigInt,
16  IMP_GetPariBigInt,
17  IMP_PariBigIntToStr,
18  IMP_PariBigIntAsciiSize
19};
20
21#if MP_DEFAULT_APINT_FORMAT == MP_PARI
22/* used to statically (i.e. at compile time) set the bigint ops -- if
23   set here, then these are the one an MP_Env is created with */
24MP_BigIntOps_t imp_default_bigint_ops =
25{
26  IMP_PutPariBigInt,
27  IMP_GetPariBigInt,
28  IMP_PariBigIntToStr,
29  IMP_PariBigIntAsciiSize
30};
31MP_BigNumFormat_t imp_default_bigint_format = MP_PARI;
32#endif
33
34/**************************************************************************
35 *
36 * Memory management routines
37 *
38 *************************************************************************/
39
40/* By default, simply use cgeti, on alloc */
41GEN IMP_DefaultAllocCgeti(long l)
42{
43  return cgeti(l);
44}
45/* and, do nothing on free */
46void IMP_DefaultFreeCgeti(GEN number)
47{}
48/* However, you might also use IMP_RawMemAlloc */
49GEN IMP_RawMemAllocCgeti(long length)
50{
51  GEN z = (GEN) IMP_RawMemAllocFnc( ((ulong)length)<<TWOPOTBYTES_IN_LONG );
52  z[0]=evaltyp(1)+evalpere(1)+evallg(length);
53  return( z );
54}
55void IMP_RawMemFreeCgeti(GEN number)
56{
57  IMP_RawMemFreeFnc(number);
58}
59
60GEN (*IMP_AllocCgeti)(long) = IMP_DefaultAllocCgeti;
61void (*IMP_FreeCgeti)(GEN) = IMP_DefaultFreeCgeti;
62
63/**************************************************************************
64 *
65 * Put/Get
66 *
67 *************************************************************************/
68
69MP_Status_t IMP_PutPariBigInt(MP_Link_pt link, MP_ApInt_t mp_number) 
70{
71  GEN number = (GEN) mp_number;
72  long length = lgef(number) - 2; /* in "limbs" */
73  long sign = signe(number); 
74
75  /* Put the length and sign */
76  ERR_CHK(IMP_PutSint32(link, (sign < 0 ? -length : length)));
77 
78  if (link->link_bigint_format == MP_PARI)
79  {
80    /* for pari - bigints can use the vector put */
81    ERR_CHK(IMP_PutUint32Vector(link, (MP_Uint32_t *) &number[2], length));
82  }
83  else
84  {
85    /* we put the numbers in the gmp format */
86    /* which is very similar to the pari format, except that in pari,
87       limbs are in descending order, and not in ascending, as in gmp */
88    GEN ptr = number + length + 1;
89    number++;
90
91    for (;ptr > number; ptr--)
92      ERR_CHK(IMP_PutLong(link, ptr));
93  }
94
95  /* done */
96  return MP_ClearError(link);
97}
98
99MP_Status_t IMP_GetPariBigInt(MP_Link_pt link, MP_ApInt_t *mp_number)
100{
101  long length, sign = 1;
102  GEN number, ptr;
103
104  /* first, we get the effective length and the sign */
105  ERR_CHK(IMP_GetLong(link, &length));
106
107  if (length < 0)
108  {
109    sign = -1;
110    length = -length;
111  }
112  else if (length == 0)
113  {
114    sign = 0;
115  }
116
117  /* Initialize the number */
118  number = IMP_AllocCgeti(length+2);
119  setlgef(number, length+2);
120  setsigne(number, sign);
121
122  /* Get the actual data */
123  if (length > 0)
124  {
125    if (link->link_bigint_format == MP_PARI)
126    {
127      ptr = &(number[2]);
128      ERR_CHK(IMP_GetUint32Vector(link, (MP_Uint32_t **) &ptr, length));
129    }
130    else
131    {
132      number++;
133      ptr = number + length;
134      for (; ptr > number; ptr--)
135        ERR_CHK(IMP_GetLong(link, ptr));
136      number--;
137    }
138  }
139
140  *mp_number = (MP_ApInt_t) number;
141  return MP_ClearError(link);
142}
143     
144long IMP_PariBigIntAsciiSize(MP_ApInt_t mp_number)
145{
146  return gsize((GEN) mp_number) + 2;
147}
148
149char * IMP_PariBigIntToStr(MP_ApInt_t mp_number, char *buffer)
150{
151//  return gitoascii((GEN) mp_number, buffer);
152  return "Can not print";
153}
154
155/* We do not really need any conversion functions. However, let's
156include them for testing purposes */
157
158#ifdef HAVE_GMP_PARI_CONVERSIONS
159
160mpz_ptr _pari_to_gmp(GEN pnum, mpz_ptr *gnum_ptr)
161{
162  mpz_ptr gnum;
163  long length = lgef(pnum) - 2;
164  long sign = signe(pnum);
165  GEN pptr;
166  mp_limb_t *gptr;
167 
168  if (*gnum_ptr == NULL)
169  {
170    *gnum_ptr = (mpz_ptr) IMP_MemAllocFnc(sizeof(__mpz_struct));
171    gnum = *gnum_ptr;
172    mpz_init(gnum);
173  }
174  else
175    gnum = *gnum_ptr;
176
177  gnum->_mp_size = (sign < 0 ? -length : length);
178
179  _mpz_realloc(gnum, length);
180  gnum->_mp_alloc = length;
181
182  gptr = gnum->_mp_d;
183  pnum++;
184  pptr = pnum + length;
185 
186  for (; pptr > pnum; gptr++, pptr--)
187    *gptr = *pptr;
188
189  return gnum;
190}
191
192GEN _gmp_to_pari(mpz_ptr gnum)
193{
194  long length = gnum->_mp_size;
195  long sign = (length < 0 ? -1 : (length == 0 ? 0 : 1));
196  GEN pnum, pptr;
197  mp_limb_t *gptr;
198
199  if (length < 0 ) length = -length;
200
201  pnum = IMP_AllocCgeti(length + 2);
202  setlgef(pnum, length + 2);
203  setsigne(pnum, sign);
204
205  pnum++;
206  pptr = pnum + length;
207  gptr = gnum->_mp_d;
208
209  for (; pptr > pnum; gptr++, pptr--)
210    *pptr = *gptr;
211
212  pnum--;
213
214  return pnum;
215}
216
217#endif
218
219 
220 
221#endif /* MP_HAVE_PARI */
Note: See TracBrowser for help on using the repository browser.