source: git/Singular/gnumpfl.cc @ 5589c0

spielwiese
Last change on this file since 5589c0 was 5589c0, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: 2-1-patches git-svn-id: file:///usr/local/Singular/svn/trunk@5331 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: gnumpfl.cc,v 1.21 2001-03-22 19:11:01 Singular 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
148number ngf_Copy(number a, ring r)
149{
150  gmp_float* b= NULL;
151  if ( a !=  NULL )
152  {
153    b= new gmp_float( *(gmp_float*)a );
154  }
155  return (number)b;
156}
157
158/*2
159* za:= - za
160*/
161number ngfNeg (number a)
162{
163  if ( a == NULL ) return NULL;
164  *(gmp_float*)a= -(*(gmp_float*)a);
165  return (number)a;
166}
167
168/*
169* 1/a
170*/
171number ngfInvers(number a)
172{
173  gmp_float* r= NULL;
174  if ( (a==NULL) /*|| ((gmp_float*)a)->isZero()*/ )
175  {
176    WerrorS("div. 1/0");
177  }
178  else
179  {
180    r= new gmp_float( (gmp_float)1 / (*(gmp_float*)a) );
181  }
182  return (number)r;
183}
184
185/*2
186* u:= a + b
187*/
188number ngfAdd (number a, number b)
189{
190  gmp_float* r= NULL;
191  if ( a==NULL && b==NULL )
192  {
193    return NULL;
194  }
195  else if ( a == NULL )
196  {
197    r= new gmp_float( *(gmp_float*)b );
198  }
199  else if ( b == NULL )
200  {
201    r= new gmp_float( *(gmp_float*)a );
202  }
203  else
204  {
205    r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
206  }
207  return (number)r;
208}
209
210/*2
211* u:= a - b
212*/
213number ngfSub (number a, number b)
214{
215  gmp_float* r= NULL;
216  if ( a==NULL && b==NULL )
217  {
218    return NULL;
219  }
220  else if ( a == NULL )
221  {
222    r= new gmp_float( -(*(gmp_float*)b) );
223  }
224  else if ( b == NULL )
225  {
226    r= new gmp_float( *(gmp_float*)a );
227  }
228  else
229  {
230    r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
231  }
232  return (number)r;
233}
234
235/*2
236* u := a * b
237*/
238number ngfMult (number a, number b)
239{
240  gmp_float* r= NULL;
241  if ( a==NULL || b==NULL )
242  {
243    return NULL;
244  }
245  else
246  {
247    r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
248  }
249  return (number)r;
250}
251
252/*2
253* u := a / b
254*/
255number ngfDiv (number a, number b)
256{
257  if ( b==NULL /*|| ((gmp_float*)b)->isZero()*/ )
258  {
259    // a/0 = error
260    WerrorS("div. 1/0");
261    return NULL;
262  }
263  else if ( a==NULL )
264  {
265    // 0/b = 0
266    return NULL;
267  }
268  gmp_float* r= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
269  return (number)r;
270}
271
272/*2
273* u:= x ^ exp
274*/
275void ngfPower ( number x, int exp, number * u )
276{
277  if ( exp == 0 )
278  {
279    gmp_float* n = new gmp_float(1);
280    *u=(number)n;
281    return;
282  }
283  if ( exp == 1 )
284  {
285    nNew(u);
286    if ( x == NULL )
287    {
288      gmp_float* n = new gmp_float();
289      *u=(number)n;
290    }
291    else
292    {
293      gmp_float* n = new gmp_float();
294      *n= *(gmp_float*)x;
295      *u=(number)n;
296    }
297    return;
298  }
299  ngfPower(x,exp-1,u);
300
301  gmp_float *n=new gmp_float();
302  *n=*(gmp_float*)x;
303  *(gmp_float*)(*u) *= *(gmp_float*)n;
304  delete (gmp_float*)n;
305}
306
307BOOLEAN ngfIsZero (number a)
308{
309  if ( a == NULL ) return TRUE;
310  return ( ((gmp_float*)a)->isZero() );
311}
312
313/*2
314* za >= 0 ?
315*/
316BOOLEAN ngfGreaterZero (number a)
317{
318  if ( a == NULL ) return TRUE;
319  return ( (*(gmp_float*)a) >= (gmp_float)0.0 );
320}
321
322/*2
323* a > b ?
324*/
325BOOLEAN ngfGreater (number a, number b)
326{
327  if ( a==NULL )
328  {
329    return (((gmp_float*)b)->sign() < 0);
330  }
331  if ( b==NULL )
332  {
333    return (((gmp_float*)a)->sign() > 0);
334  }
335  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
336}
337
338/*2
339* a = b ?
340*/
341BOOLEAN ngfEqual (number a, number b)
342{
343  if ( a == NULL && b == NULL )
344  {
345    return TRUE;
346  }
347  else if ( a == NULL || b == NULL )
348  {
349    return FALSE;
350  }
351  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
352}
353
354/*2
355* a == 1 ?
356*/
357BOOLEAN ngfIsOne (number a)
358{
359  if ( a == NULL ) return FALSE;
360  return ((gmp_float*)a)->isOne();
361}
362
363/*2
364* a == -1 ?
365*/
366BOOLEAN ngfIsMOne (number a)
367{
368  if ( a == NULL ) return FALSE;
369  return ((gmp_float*)a)->isMOne();
370}
371
372/*2
373* result =gcd(a,b)
374* dummy, returns 1
375*/
376number ngfGcd(number a, number b)
377{
378  gmp_float *result= new gmp_float( 1 );
379  return (number)result;
380}
381
382char * ngfEatFloatNExp( char * s )
383{
384  char *start= s;
385
386  // eat floats (mantissa) like:
387  //   0.394394993, 102.203003008,  .300303032
388  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
389
390  // eat the exponent, starts with 'e' followed by '+', '-'
391  // and digits, like:
392  //   e-202, e+393
393  if ( (s != start) && (*s == 'e') && ((*(s+1) == '+') || (*(s+1) == '-')) )
394  {
395    s=s+2; // eat e and sign
396    while ((*s >= '0' && *s <= '9')) s++;
397  }
398
399  return s;
400}
401
402/*2
403* extracts the number a from s, returns the rest
404*/
405char * ngfRead (char * s, number * a)
406{
407  char *start= s;
408
409  //Print("%s\n",s);
410
411  s= ngfEatFloatNExp( s );
412
413  if (*s=='\0')  // 0
414  {
415    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
416    (*(gmp_float**)a)->setFromStr(start);
417  }
418  else if (s==start)  // 1
419  {
420    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
421    (*(gmp_float**)a)= new gmp_float(1);
422  }
423  else
424  {
425    gmp_float divisor(1.0);
426    char *start2=s;
427    if ( *s == '/' )
428    {
429      s++;
430      s= ngfEatFloatNExp( s );
431      if (s!= start2+1)
432      {
433        char tmp_c=*s;
434        *s='\0';
435        divisor.setFromStr(start2+1);
436        *s=tmp_c;
437      }
438      else
439      {
440        Werror("wrong long real format: %s",start2);
441      }
442    }
443    char c=*start2;
444    *start2='\0';
445    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
446    (*(gmp_float**)a)->setFromStr(start);
447    *start2=c;
448    (**(gmp_float**)a) /= divisor;
449  }
450
451  return s;
452}
453
454/*2
455* write a floating point number
456*/
457void ngfWrite (number &a)
458{
459  char *out;
460  if ( a != NULL )
461  {
462    out= floatToStr(*(gmp_float*)a,gmp_output_digits);
463    StringAppend(out);
464    //omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
465    omFree( (ADDRESS)out );
466  }
467  else
468  {
469    StringAppend("0");
470  }
471}
472
473#ifdef LDEBUG
474BOOLEAN ngfDBTest(number a, char *f, int l)
475{
476  return TRUE;
477}
478#endif
479
480// local Variables: ***
481// folded-file: t ***
482// compile-command: "make installg" ***
483// End: ***
Note: See TracBrowser for help on using the repository browser.