source: git/Singular/gnumpfl.cc @ 57e94c4

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