source: git/coeffs/shortfl.cc @ 7d90aa

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