source: git/Singular/shortfl.cc @ 82716e

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