source: git/Singular/shortfl.cc @ 50cbdc

spielwiese
Last change on this file since 50cbdc was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 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: shortfl.cc,v 1.19 2001-08-27 14:47:39 Singular Exp $ */
5
6/*
7* ABSTRACT:
8*/
9
10#include <string.h>
11#include "mod2.h"
12#include <mylimits.h>
13#include "tok.h"
14#include "febase.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "mpr_complex.h"
18#include "ring.h"
19#include "shortfl.h"
20
21static float nrEps = 1.0e-3;
22union nf
23{
24  float _f;
25  number _n;
26  nf(float f) {_f = f;}
27  nf(number n) {_n = n;}
28  float F() const {return _f;}
29  number N() const {return _n;}
30};
31
32float nrFloat(number n)
33{
34  return nf(n).F();
35}
36
37BOOLEAN nrGreaterZero (number k)
38{
39  return nf(k).F() >= 0.0;
40}
41
42number nrMult (number a,number b)
43{
44  return nf(nf(a).F() * nf(b).F()).N();
45}
46
47/*2
48* create a number from int
49*/
50number nrInit (int i)
51{
52  float r = (float)i;
53  return nf(nf(r).F()).N();
54}
55
56/*2
57* convert a number to int
58*/
59int nrInt(number &n)
60{
61  int i;
62  float r = nf(n).F();
63  if (((float)INT_MIN <= r) || ((float)MAX_INT_VAL >= r))
64    i = (int)r;
65  else
66    i = 0;
67  return i;
68}
69
70number nrAdd (number a, number b)
71{
72  float x = nf(a).F();
73  float y = nf(b).F();
74  float r = x + y;
75  if (x > 0.0)
76  {
77    if (y < 0.0)
78    {
79      x = r / (x - y);
80      if (x < 0.0)
81        x = -x;
82      if (x < nrEps)
83        r = 0.0;
84    }
85  }
86  else
87  {
88    if (y > 0.0)
89    {
90      x = r / (y - x);
91      if (x < 0.0)
92        x = -x;
93      if (x < nrEps)
94        r = 0.0;
95    }
96  }
97  return nf(r).N();
98}
99
100number nrSub (number a, number b)
101{
102  float x = nf(a).F();
103  float y = nf(b).F();
104  float r = x - y;
105  if (x > 0.0)
106  {
107    if (y > 0.0)
108    {
109      x = r / (x + y);
110      if (x < 0.0)
111        x = -x;
112      if (x < nrEps)
113        r = 0.0;
114    }
115  }
116  else
117  {
118    if (y < 0.0)
119    {
120      x = r / (x + y);
121      if (x < 0.0)
122        x = -x;
123      if (x < nrEps)
124        r = 0.0;
125    }
126  }
127  return nf(r).N();
128}
129
130BOOLEAN nrIsZero (number  a)
131{
132  return (0.0 == nf(a).F());
133}
134
135BOOLEAN nrIsOne (number a)
136{
137  float aa=nf(a).F()-1.0;
138  if (aa<0.0) aa=-aa;
139  return (aa<nrEps);
140}
141
142BOOLEAN nrIsMOne (number a)
143{
144  float aa=nf(a).F()+1.0;
145  if (aa<0.0) aa=-aa;
146  return (aa<nrEps);
147}
148
149number nrDiv (number a,number b)
150{
151  float n = nf(b).F();
152  if (n == 0.0)
153  {
154    WerrorS("a/0");
155    return nf((float)0.0).N();
156  }
157  else
158    return nf(nf(a).F() / n).N();
159}
160
161number  nrInvers (number c)
162{
163  float n = nf(c).F();
164  if (n == 0.0)
165  {
166    WerrorS("1/0");
167    return nf((float)0.0).N();
168  }
169  return nf(1.0 / n).N();
170}
171
172number nrNeg (number c)
173{
174  return nf(-nf(c).F()).N();
175}
176
177BOOLEAN nrGreater (number a,number b)
178{
179  return nf(a).F() > nf(b).F();
180}
181
182BOOLEAN nrEqual (number a,number b)
183{
184  number x = nrSub(a,b);
185  return nf(x).F() == nf((float)0.0).F();
186}
187
188void nrWrite (number &a)
189{
190  StringAppend("%9.3e", nf(a).F());
191}
192
193void nrPower (number a, int i, number * result)
194{
195  if (i==0)
196  {
197    *result = nf(nf(1.0).F()).N();
198    return;
199  }
200  if (i==1)
201  {
202    *result = nf(nf(a).F()).N();
203    return;
204  }
205  nrPower(a,i-1,result);
206  *result = nf(nf(a).F() * nf(*result).F()).N();
207}
208
209char* nrEatr(char *s, float *r)
210{
211  int i;
212
213  if    (*s >= '0' && *s <= '9')
214  {
215    *r = 0.0;
216    do
217    {
218      *r *= 10.0;
219      i = *s++ - '0';
220      *r += (float)i;
221    }
222    while (*s >= '0' && *s <= '9');
223  }
224  else *r = 1.0;
225  return s;
226}
227
228char * nrRead (char *s, number *a)
229{
230  char *t;
231  float z1,z2;
232  float n=1.0;
233
234  s = nrEatr(s, &z1);
235  if (*s == '/')
236  {
237    s++;
238    s = nrEatr(s, &z2);
239    z1 /= z2;
240  }
241  else if (*s =='.')
242  {
243    s++;
244    t = s;
245    while (*t >= '0' && *t <= '9')
246    {
247      t++;
248      n *= 10.0;
249    }
250    s = nrEatr(s, &z2);
251    z1 = (z1*n + z2) / n;
252    if (*s=='e')
253    {
254      int e=0; /* exponent */
255      int si=1;/* sign of exponent */
256      s++;
257      if (*s=='+') s++;
258      else if (*s=='-') {s++; si=-1; }
259      while (*s >= '0' && *s <= '9')
260      {
261        e=e*10+(*s)-'0';
262        s++;
263      }
264      if (si==1)
265      {
266        while (e>0) {z1*=10.0; e--; }
267      }
268      else
269      {
270        while (e>0) {z1/=10.0; e--; }
271      }
272    }
273  }
274  *a = nf(z1).N();
275  return s;
276}
277
278/*2
279* the last used charcteristic
280*/
281int nrGetChar()
282{
283  return 0;
284}
285
286#ifdef LDEBUG
287/*2
288* test valid numbers: not implemented yet
289*/
290BOOLEAN nrDBTest(number a, char *f, int l)
291{
292  return TRUE;
293}
294#endif
295
296/* in longrat.h
297typedef MP_INT lint;
298#define SR_INT    1
299#ifdef HAVE_LIBGMP1
300#define mpz_size1(A) (ABS((A)->size))
301#else
302#define mpz_size1(A) (ABS((A)->_mp_size))
303#endif
304*/
305#define SR_HDL(A) ((long)(A))
306#ifdef HAVE_LIBGMP1
307#define mpz_isNeg(A) ((A)->size<0)
308#define mpz_limb_size(A) ((A)->size)
309#define mpz_limb_d(A) ((A)->d)
310#define MPZ_DIV(A,B,C) mpz_div((A),(B),(C))
311#else
312#define mpz_isNeg(A) ((A)->_mp_size<0)
313#define mpz_limb_size(A) ((A)->_mp_size)
314#define mpz_limb_d(A) ((A)->_mp_d)
315#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
316#endif
317#define IS_INT(A) ((A)->s==3)
318#define IS_IMM(A) (SR_HDL(A)&SR_INT)
319#define GET_NOM(A) &((A)->z)
320#define GET_DENOM(A) &((A)->n)
321#define MPZ_INIT mpz_init
322#define MPZ_CLEAR mpz_clear
323
324static number nrMapQ(number from)
325{
326  lint h,*g,*z,*n;
327  int i,j,t,s;
328  float ba,rr,rn,y;
329
330  if (IS_IMM(from))
331    return nf((float)nlInt(from)).N();
332  z=GET_NOM(from);
333  s=0X10000;
334  ba=(float)s;
335  ba*=ba;
336  rr=0.0;
337  i=mpz_size1(z);
338  if(IS_INT(from))
339  {
340    if(i>4)
341    {
342      WerrorS("float overflow");
343      return nf(rr).N();
344    }
345    i--;
346    rr=(float)mpz_limb_d(z)[i];
347    while(i>0)
348    {
349      i--;
350      y=(float)mpz_limb_d(z)[i];
351      rr=rr*ba+y;
352    }
353    if(mpz_isNeg(z))
354      rr=-rr;
355    return nf(rr).N();
356  }
357  n=GET_DENOM(from);
358  j=s=mpz_limb_size(n);
359  if(j>i)
360  {
361    g=n; n=z; z=g;
362    t=j; j=i; i=t;
363  }
364  t=i-j;
365  if(t>4)
366  {
367    if(j==s)
368      WerrorS("float overflow");
369    return nf(rr).N();
370  }
371  if(t>1)
372  {
373    g=&h;
374    MPZ_INIT(g);
375    MPZ_DIV(g,z,n);
376    t=mpz_size1(g);
377    if(t>4)
378    {
379      MPZ_CLEAR(g);
380      if(j==s)
381        WerrorS("float overflow");
382      return nf(rr).N();
383    }
384    t--;
385    rr=(float)mpz_limb_d(g)[t];
386    while(t)
387    {
388      t--;
389      y=(float)mpz_limb_d(g)[t];
390      rr=rr*ba+y;
391    }
392    MPZ_CLEAR(g);
393    if(j!=s)
394      rr=1.0/rr;
395    if(mpz_isNeg(z))
396      rr=-rr;
397    return nf(rr).N();
398  }
399  rn=(float)mpz_limb_d(n)[j-1];
400  rr=(float)mpz_limb_d(z)[i-1];
401  if(j>1)
402  {
403    rn=rn*ba+(float)mpz_limb_d(n)[j-2];
404    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
405    i--;
406  }
407  if(t!=0)
408    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
409  if(j==s)
410    rr=rr/rn;
411  else
412    rr=rn/rr;
413  if(mpz_isNeg(z))
414    rr=-rr;
415  return nf(rr).N();
416}
417
418static number nrMapP(number from)
419{
420  int i = (int)from;
421  float r = (float)i;
422  return nf(r).N();
423}
424
425static number nrMapLongR(number from)
426{
427  float t =(float)mpf_get_d((mpf_srcptr)from);
428  return nf(t).N();
429}
430static number nrMapC(number from)
431{
432  gmp_float h = ((gmp_complex*)from)->real();
433  float t =(float)mpf_get_d((mpf_srcptr)&h);
434  return nf(t).N();
435}
436
437nMapFunc nrSetMap(ring src, ring dst)
438{
439  if (rField_is_Q(src))
440  {
441    return nrMapQ;
442  }
443  if (rField_is_long_R(src))
444  {
445    return nrMapLongR;
446  }
447  if (rField_is_R(src))
448  {
449    return ndCopy;
450  }
451  if(rField_is_Zp(src))
452  {
453    return nrMapP;
454  }
455  if (rField_is_long_C(src))
456  {
457    return nrMapC;
458  }
459  return NULL;
460}
Note: See TracBrowser for help on using the repository browser.