source: git/Singular/gnumpfl.cc @ 6e5e20

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