source: git/Singular/shortfl.cc @ 9235af

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