source: git/Singular/gnumpfl.cc @ 63d4d8

spielwiese
Last change on this file since 63d4d8 was 63d4d8, checked in by Wilfred Pohl <pohl@…>, 23 years ago
maps git-svn-id: file:///usr/local/Singular/svn/trunk@5132 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: gnumpfl.cc,v 1.20 2001-01-30 11:45:47 pohl Exp $ */
5/*
6* ABSTRACT: computations with GMP floating-point numbers
7*
8* ngf == number gnu floats
9*/
10
11#include "mod2.h"
12#include "tok.h"
13#include "febase.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
24static number ngfMapP(number from)
25{
26  if ( from != NULL)
27    return ngfInit(npInt(from));
28  else
29    return NULL;
30}
31static number ngfMapQ(number from)
32{
33  if ( from != NULL )
34  {
35    gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
36    return (number)res;
37  }
38  else
39    return NULL;
40}
41union nf
42{
43  float _f;
44  number _n;
45  nf(float f) {_f = f;}
46  nf(number n) {_n = n;}
47  float F() const {return _f;}
48  number N() const {return _n;}
49};
50static number ngfMapR(number from)
51{
52  if ( from != NULL )
53  {
54    gmp_float *res=new gmp_float((double)nf(from).F());
55    return (number)res;
56  }
57  else
58    return NULL;
59}
60static number ngfMapC(number from)
61{
62  if ( (from != NULL) || ((gmp_complex*)from)->real().isZero() )
63  {
64    gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
65    return (number)res;
66  }
67  else
68    return NULL;
69}
70
71nMapFunc ngfSetMap(ring src, ring dst)
72{
73  if (rField_is_Q(src))
74  {
75    return ngfMapQ;
76  }
77  if (rField_is_long_R(src))
78  {
79    return ngfCopy;
80  }
81  if (rField_is_R(src))
82  {
83    return ngfMapR;
84  }
85  if (rField_is_Zp(src))
86  {
87    return ngfMapP;
88  }
89  if (rField_is_long_C(src))
90  {
91    return ngfMapC;
92  }
93  return NULL;
94}
95
96void ngfNew (number * r)
97{
98  *r= NULL;
99}
100
101/*2
102* n := i
103*/
104number ngfInit (int i)
105{
106  gmp_float* n= NULL;
107  if ( i != 0 )
108  {
109    n= new gmp_float( (double)i );
110  }
111  return (number)n;
112}
113
114/*2
115* convert number to int
116*/
117int ngfInt(number &i)
118{
119  if ( i == NULL ) return 0;
120  return (int)*(gmp_float*)i;
121}
122
123/*2
124* delete a
125*/
126void ngfDelete (number * a, const ring r)
127{
128  if ( *a != NULL )
129  {
130    delete *(gmp_float**)a;
131    *a=NULL;
132  }
133}
134
135/*2
136* copy a to b
137*/
138number ngfCopy(number a)
139{
140  gmp_float* b= NULL;
141  if ( a !=  NULL )
142  {
143    b= new gmp_float( *(gmp_float*)a );
144  }
145  return (number)b;
146}
147
148/*2
149* za:= - za
150*/
151number ngfNeg (number a)
152{
153  if ( a == NULL ) return NULL;
154  *(gmp_float*)a= -(*(gmp_float*)a);
155  return (number)a;
156}
157
158/*
159* 1/a
160*/
161number ngfInvers(number a)
162{
163  gmp_float* r= NULL;
164  if ( (a==NULL) /*|| ((gmp_float*)a)->isZero()*/ )
165  {
166    WerrorS("div. 1/0");
167  }
168  else
169  {
170    r= new gmp_float( (gmp_float)1 / (*(gmp_float*)a) );
171  }
172  return (number)r;
173}
174
175/*2
176* u:= a + b
177*/
178number ngfAdd (number a, number b)
179{
180  gmp_float* r= NULL;
181  if ( a==NULL && b==NULL )
182  {
183    return NULL;
184  }
185  else if ( a == NULL )
186  {
187    r= new gmp_float( *(gmp_float*)b );
188  }
189  else if ( b == NULL )
190  {
191    r= new gmp_float( *(gmp_float*)a );
192  }
193  else
194  {
195    r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
196  }
197  return (number)r;
198}
199
200/*2
201* u:= a - b
202*/
203number ngfSub (number a, number b)
204{
205  gmp_float* r= NULL;
206  if ( a==NULL && b==NULL )
207  {
208    return NULL;
209  }
210  else if ( a == NULL )
211  {
212    r= new gmp_float( -(*(gmp_float*)b) );
213  }
214  else if ( b == NULL )
215  {
216    r= new gmp_float( *(gmp_float*)a );
217  }
218  else
219  {
220    r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
221  }
222  return (number)r;
223}
224
225/*2
226* u := a * b
227*/
228number ngfMult (number a, number b)
229{
230  gmp_float* r= NULL;
231  if ( a==NULL || b==NULL )
232  {
233    return NULL;
234  }
235  else
236  {
237    r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
238  }
239  return (number)r;
240}
241
242/*2
243* u := a / b
244*/
245number ngfDiv (number a, number b)
246{
247  if ( b==NULL /*|| ((gmp_float*)b)->isZero()*/ )
248  {
249    // a/0 = error
250    WerrorS("div. 1/0");
251    return NULL;
252  }
253  else if ( a==NULL )
254  {
255    // 0/b = 0
256    return NULL;
257  }
258  gmp_float* r= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
259  return (number)r;
260}
261
262/*2
263* u:= x ^ exp
264*/
265void ngfPower ( number x, int exp, number * u )
266{
267  if ( exp == 0 )
268  {
269    gmp_float* n = new gmp_float(1);
270    *u=(number)n;
271    return;
272  }
273  if ( exp == 1 )
274  {
275    nNew(u);
276    if ( x == NULL )
277    {
278      gmp_float* n = new gmp_float();
279      *u=(number)n;
280    }
281    else
282    {
283      gmp_float* n = new gmp_float();
284      *n= *(gmp_float*)x;
285      *u=(number)n;
286    }
287    return;
288  }
289  ngfPower(x,exp-1,u);
290
291  gmp_float *n=new gmp_float();
292  *n=*(gmp_float*)x;
293  *(gmp_float*)(*u) *= *(gmp_float*)n;
294  delete (gmp_float*)n;
295}
296
297BOOLEAN ngfIsZero (number a)
298{
299  if ( a == NULL ) return TRUE;
300  return ( ((gmp_float*)a)->isZero() );
301}
302
303/*2
304* za >= 0 ?
305*/
306BOOLEAN ngfGreaterZero (number a)
307{
308  if ( a == NULL ) return TRUE;
309  return ( (*(gmp_float*)a) >= (gmp_float)0.0 );
310}
311
312/*2
313* a > b ?
314*/
315BOOLEAN ngfGreater (number a, number b)
316{
317  if ( a==NULL )
318  {
319    return (((gmp_float*)b)->sign() < 0);
320  }
321  if ( b==NULL )
322  {
323    return (((gmp_float*)a)->sign() > 0);
324  }
325  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
326}
327
328/*2
329* a = b ?
330*/
331BOOLEAN ngfEqual (number a, number b)
332{
333  if ( a == NULL && b == NULL )
334  {
335    return TRUE;
336  }
337  else if ( a == NULL || b == NULL )
338  {
339    return FALSE;
340  }
341  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
342}
343
344/*2
345* a == 1 ?
346*/
347BOOLEAN ngfIsOne (number a)
348{
349  if ( a == NULL ) return FALSE;
350  return ((gmp_float*)a)->isOne();
351}
352
353/*2
354* a == -1 ?
355*/
356BOOLEAN ngfIsMOne (number a)
357{
358  if ( a == NULL ) return FALSE;
359  return ((gmp_float*)a)->isMOne();
360}
361
362/*2
363* result =gcd(a,b)
364* dummy, returns 1
365*/
366number ngfGcd(number a, number b)
367{
368  gmp_float *result= new gmp_float( 1 );
369  return (number)result;
370}
371
372char * ngfEatFloatNExp( char * s )
373{
374  char *start= s;
375
376  // eat floats (mantissa) like:
377  //   0.394394993, 102.203003008,  .300303032
378  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
379
380  // eat the exponent, starts with 'e' followed by '+', '-'
381  // and digits, like:
382  //   e-202, e+393
383  if ( (s != start) && (*s == 'e') && ((*(s+1) == '+') || (*(s+1) == '-')) )
384  {
385    s=s+2; // eat e and sign
386    while ((*s >= '0' && *s <= '9')) s++;
387  }
388
389  return s;
390}
391
392/*2
393* extracts the number a from s, returns the rest
394*/
395char * ngfRead (char * s, number * a)
396{
397  char *start= s;
398
399  //Print("%s\n",s);
400
401  s= ngfEatFloatNExp( s );
402
403  if (*s=='\0')  // 0
404  {
405    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
406    (*(gmp_float**)a)->setFromStr(start);
407  }
408  else if (s==start)  // 1
409  {
410    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
411    (*(gmp_float**)a)= new gmp_float(1);
412  }
413  else
414  {
415    gmp_float divisor(1.0);
416    char *start2=s;
417    if ( *s == '/' )
418    {
419      s++;
420      s= ngfEatFloatNExp( s );
421      if (s!= start2+1)
422      {
423        char tmp_c=*s;
424        *s='\0';
425        divisor.setFromStr(start2+1);
426        *s=tmp_c;
427      }
428      else
429      {
430        Werror("wrong long real format: %s",start2);
431      }
432    }
433    char c=*start2;
434    *start2='\0';
435    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
436    (*(gmp_float**)a)->setFromStr(start);
437    *start2=c;
438    (**(gmp_float**)a) /= divisor;
439  }
440
441  return s;
442}
443
444/*2
445* write a floating point number
446*/
447void ngfWrite (number &a)
448{
449  char *out;
450  if ( a != NULL )
451  {
452    out= floatToStr(*(gmp_float*)a,gmp_output_digits);
453    StringAppend(out);
454    //omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
455    omFree( (ADDRESS)out );
456  }
457  else
458  {
459    StringAppend("0");
460  }
461}
462
463#ifdef LDEBUG
464BOOLEAN ngfDBTest(number a, char *f, int l)
465{
466  return TRUE;
467}
468#endif
469
470// local Variables: ***
471// folded-file: t ***
472// compile-command: "make installg" ***
473// End: ***
Note: See TracBrowser for help on using the repository browser.