source: git/coeffs/gnumpfl.cc @ 502f7e8

fieker-DuValspielwiese
Last change on this file since 502f7e8 was f945d2b, checked in by Oleksandr Motsak <motsak@…>, 14 years ago
no mpf_pow? using mpf_pow_ui... + correct operator^ overloading (resp. its usage)
  • Property mode set to 100644
File size: 6.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: computations with GMP floating-point numbers
7*
8* ngf == number gnu floats
9*/
10
11#include "config.h"
12#include "coeffs.h"
13#include <output.h>
14#include <omalloc.h>
15#include "numbers.h"
16#include "modulop.h"
17#include "longrat.h"
18
19#include <gnumpfl.h>
20#include <mpr_complex.h>
21
22extern size_t gmp_output_digits;
23//ring ngfMapRing; // to be used also in gnumpc.cc
24
25static number ngfMapP(number from, const coeffs src, const coeffs dst)
26{
27  return ngfInit(npInt(from,src), dst);
28}
29number ngfMapQ(number from, const coeffs src, const coeffs dst)
30{
31  gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
32  return (number)res;
33}
34union nf
35{
36  float _f;
37  number _n;
38  nf(float f) {_f = f;}
39  nf(number n) {_n = n;}
40  float F() const {return _f;}
41  number N() const {return _n;}
42};
43static number ngfMapR(number from, const coeffs src, const coeffs dst)
44{
45  gmp_float *res=new gmp_float((double)nf(from).F());
46  return (number)res;
47}
48static number ngfMapC(number from, const coeffs src, const coeffs dst)
49{
50  gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
51  return (number)res;
52}
53
54nMapFunc ngfSetMap(const ring src, const ring dst)
55{
56  if (rField_is_Q(src))
57  {
58    return ngfMapQ;
59  }
60  if (rField_is_long_R(src))
61  {
62    return ngfCopy;
63  }
64  if (rField_is_R(src))
65  {
66    return ngfMapR;
67  }
68  if (rField_is_Zp(src))
69  {
70    ngfMapRing=src;
71    return ngfMapP;
72  }
73  if (rField_is_long_C(src))
74  {
75    return ngfMapC;
76  }
77  return NULL;
78}
79
80/*2
81* n := i
82*/
83number ngfInit (int i, const coeffs r)
84{
85  gmp_float* n= new gmp_float( (double)i );
86  return (number)n;
87}
88
89/*2
90* convert number to int
91*/
92int ngfInt(number &i, const coeffs r)
93{
94  double d=(double)*(gmp_float*)i;
95  if (d<0.0)
96    return (int)(d-0.5);
97  else
98    return (int)(d+0.5);
99}
100
101int ngfSize(number n, const coeffs r)
102{
103  int i = ngfInt(n, r);
104  /* basically return the largest integer in n;
105     only if this happens to be zero although n != 0,
106     return 1;
107     (this code ensures that zero has the size zero) */
108  if ((i == 0) && (ngfIsZero(n) == FALSE)) i = 1;
109  return i;
110}
111
112/*2
113* delete a
114*/
115void ngfDelete (number * a, const coeffs r)
116{
117  if ( *a != NULL )
118  {
119    delete *(gmp_float**)a;
120    *a=NULL;
121  }
122}
123
124/*2
125* copy a to b
126*/
127number ngfCopy(number a, const coeffs r)
128{
129  gmp_float* b= new gmp_float( *(gmp_float*)a );
130  return (number)b;
131}
132
133/*2
134* za:= - za
135*/
136number ngfNeg (number a, const coeffs r)
137{
138  *(gmp_float*)a= -(*(gmp_float*)a);
139  return (number)a;
140}
141
142/*
143* 1/a
144*/
145number ngfInvers(number a, const coeffs R)
146{
147  gmp_float* r= NULL;
148  if (((gmp_float*)a)->isZero() )
149  {
150    WerrorS(nDivBy0);
151  }
152  else
153  {
154    f= new gmp_float( gmp_float(1) / (*(gmp_float*)a) );
155  }
156  return (number)f;
157}
158
159/*2
160* u:= a + b
161*/
162number ngfAdd (number a, number b, const coeffs R)
163{
164  gmp_float* r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
165  return (number)r;
166}
167
168/*2
169* u:= a - b
170*/
171number ngfSub (number a, number b, const coeffs R)
172{
173  gmp_float* r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
174  return (number)r;
175}
176
177/*2
178* u := a * b
179*/
180number ngfMult (number a, number b, const coeffs R)
181{
182  gmp_float* r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
183  return (number)r;
184}
185
186/*2
187* u := a / b
188*/
189number ngfDiv (number a, number b, const coeffs r)
190{
191  if ( ((gmp_float*)b)->isZero() )
192  {
193    // a/0 = error
194    WerrorS(nDivBy0);
195    return NULL;
196  }
197  gmp_float* f= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
198  return (number)f;
199}
200
201/*2
202* u:= x ^ exp
203*/
204number ngfPower (number x, int exp, const coeffs r)
205{
206  if ( exp == 0 )
207  {
208    gmp_float* n = new gmp_float(1);
209    *u=(number)n;
210    return;
211  }
212  else if ( ngfIsZero(x, r) ) // 0^e, e>0
213  {
214    *u=ngfInit(0, r);
215    return;
216  }
217  else if ( exp == 1 )
218  {
219    n_New(u, r);
220    gmp_float* n = new gmp_float();
221    *n= *(gmp_float*)x;
222    *u=(number)n;
223    return;
224  }
225  return (number) ( new gmp_float( (*(gmp_float*)x)^exp ) );
226}
227
228/* kept for compatibility reasons, to be deleted */
229void ngfPower ( number x, int exp, number * u, const coeffs r )
230{
231  *u = ngfPower(x, exp, r);
232} 
233
234BOOLEAN ngfIsZero (number a, const coeffs r)
235{
236  return ( ((gmp_float*)a)->isZero() );
237}
238
239/*2
240* za > 0 ?
241*/
242BOOLEAN ngfGreaterZero (number a, const coeffs r)
243{
244  return (((gmp_float*)a)->sign() > 0);
245}
246
247/*2
248* a > b ?
249*/
250BOOLEAN ngfGreater (number a, number b, const coeffs r)
251{
252  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
253}
254
255/*2
256* a = b ?
257*/
258BOOLEAN ngfEqual (number a, number b, const coeffs r)
259{
260  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
261}
262
263/*2
264* a == 1 ?
265*/
266BOOLEAN ngfIsOne (number a, const coeffs r)
267{
268  return ((gmp_float*)a)->isOne();
269}
270
271/*2
272* a == -1 ?
273*/
274BOOLEAN ngfIsMOne (number a, const coeffs r)
275{
276  return ((gmp_float*)a)->isMOne();
277}
278
279static char * ngfEatFloatNExp(char * s )
280{
281  char *start= s;
282
283  // eat floats (mantissa) like:
284  //   0.394394993, 102.203003008,  .300303032, pssibly starting with -
285  if (*s == '-') s++;
286  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
287
288  // eat the exponent, starts with 'e' followed by '+', '-'
289  // and digits, like:
290  //   e-202, e+393, accept also E7
291  if ( (s != start) && ((*s == 'e')||(*s=='E')))
292  {
293    if (*s=='E') *s='e';
294    s++; // skip 'e'/'E'
295    if ((*s == '+') || (*s == '-')) s++;
296    while ((*s >= '0' && *s <= '9')) s++;
297  }
298
299  return s;
300}
301
302/*2
303* extracts the number a from s, returns the rest
304*/
305const char * ngfRead (const char * start, number * a, const coeffs r)
306{
307  char *s= (char *)start;
308
309  //Print("%s\n",s);
310
311  s= ngfEatFloatNExp( s );
312
313  if (*s=='\0')  // 0
314  {
315    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
316    (*(gmp_float**)a)->setFromStr(start);
317  }
318  else if (s==start)  // 1
319  {
320    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
321    (*(gmp_float**)a)= new gmp_float(1);
322  }
323  else
324  {
325    gmp_float divisor(1.0);
326    char *start2=s;
327    if ( *s == '/' )
328    {
329      s++;
330      s= ngfEatFloatNExp( (char *)s );
331      if (s!= start2+1)
332      {
333        char tmp_c=*s;
334        *s='\0';
335        divisor.setFromStr(start2+1);
336        *s=tmp_c;
337      }
338      else
339      {
340        Werror("wrong long real format: %s",start2);
341      }
342    }
343    char c=*start2;
344    *start2='\0';
345    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
346    (*(gmp_float**)a)->setFromStr(start);
347    *start2=c;
348    if (divisor.isZero())
349    {
350      WerrorS(nDivBy0);
351    }
352    else
353      (**(gmp_float**)a) /= divisor;
354  }
355
356  return s;
357}
358
359/*2
360* write a floating point number
361*/
362void ngfWrite (number &a, const coeffs r)
363{
364  char *out;
365  if ( a != NULL )
366  {
367    out= floatToStr(*(gmp_float*)a,gmp_output_digits);
368    StringAppendS(out);
369    //omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
370    omFree( (void *)out );
371  }
372  else
373  {
374    StringAppendS("0");
375  }
376}
377
Note: See TracBrowser for help on using the repository browser.