source: git/Singular/gnumpfl.cc @ 5fecb3

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