source: git/Singular/gnumpfl.cc @ 2082b6

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