source: git/coeffs/shortfl.cc @ dc093ce

spielwiese
Last change on this file since dc093ce was dc093ce, checked in by Oleksandr Motsak <motsak@…>, 14 years ago
Switched aRing and r to "src, dst"
  • Property mode set to 100644
File size: 9.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6/*
7* ABSTRACT:
8*/
9
10#include "shortfl.h"
11
12#include <string.h>
13#include "coeffs.h"
14#include "output.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "mpr_complex.h"
18
19#include <mylimits.h>
20// #include "limits.h"
21
22// #ifndef assume
23// #  define assume(a) if(!(a)){ Werror( "Assumption: is wrong: %s\n", #a ); };
24// #endif
25
26
27
28static const n_coeffType ID = n_R;
29
30static const float nrEps = 1.0e-3;
31
32union nf
33{
34  float _f;
35  number _n;
36
37  nf(float f): _f(f){};
38
39  nf(number n): _n(n){};
40
41  inline float F() const {return _f;}
42  inline number N() const {return _n;}
43};
44
45
46
47
48float nrFloat(number n)
49{
50  return nf(n).F();
51}
52
53
54BOOLEAN nrGreaterZero (number k, const coeffs r)
55{
56  assume( getCoeffType(r) == ID );
57
58  return nf(k).F() >= 0.0;
59}
60
61number nrMult (number a,number b, const coeffs r)
62{
63  assume( getCoeffType(r) == ID );
64
65  return nf(nf(a).F() * nf(b).F()).N();
66}
67
68/*2
69* create a number from int
70*/
71number nrInit (int i, const coeffs r)
72{
73  assume( getCoeffType(r) == ID );
74
75  float f = (float)i;
76  return nf(nf(f).F()).N();
77}
78
79/*2
80* convert a number to int
81*/
82int nrInt(number &n, const coeffs r)
83{
84  assume( getCoeffType(r) == ID );
85
86  int i;
87  float f = nf(n).F();
88  if (((float)INT_MIN <= f) || ((float)INT_MAX >= f))
89    i = (int)f;
90  else
91    i = 0;
92  return i;
93}
94
95int nrSize(number n, const coeffs R)
96{
97  float f = nf(n).F();
98  int i = (int)f;
99  /* basically return the largest integer in n;
100     only if this happens to be zero although n != 0,
101     return 1;
102     (this code ensures that zero has the size zero) */
103  if ((f != 0.0) & (i == 0)) i = 1;
104  return i;
105}
106
107number nrAdd (number a, number b, const coeffs r)
108{
109  assume( getCoeffType(r) == ID );
110
111  float x = nf(a).F();
112  float y = nf(b).F();
113  float f = x + y;
114  if (x > 0.0)
115  {
116    if (y < 0.0)
117    {
118      x = f / (x - y);
119      if (x < 0.0)
120        x = -x;
121      if (x < nrEps)
122        f = 0.0;
123    }
124  }
125  else
126  {
127    if (y > 0.0)
128    {
129      x = f / (y - x);
130      if (x < 0.0)
131        x = -x;
132      if (x < nrEps)
133        f = 0.0;
134    }
135  }
136  return nf(f).N();
137}
138
139number nrSub (number a, number b, const coeffs r)
140{
141  assume( getCoeffType(r) == ID );
142
143  float x = nf(a).F();
144  float y = nf(b).F();
145  float f = x - y;
146  if (x > 0.0)
147  {
148    if (y > 0.0)
149    {
150      x = f / (x + y);
151      if (x < 0.0)
152        x = -x;
153      if (x < nrEps)
154        f = 0.0;
155    }
156  }
157  else
158  {
159    if (y < 0.0)
160    {
161      x = f / (x + y);
162      if (x < 0.0)
163        x = -x;
164      if (x < nrEps)
165        f = 0.0;
166    }
167  }
168  return nf(f).N();
169}
170
171BOOLEAN nrIsZero (number  a, const coeffs r)
172{
173  assume( getCoeffType(r) == ID );
174
175  return (0.0 == nf(a).F());
176}
177
178BOOLEAN nrIsOne (number a, const coeffs r)
179{
180  assume( getCoeffType(r) == ID );
181
182  float aa=nf(a).F()-1.0;
183  if (aa<0.0) aa=-aa;
184  return (aa<nrEps);
185}
186
187BOOLEAN nrIsMOne (number a, const coeffs r)
188{
189  assume( getCoeffType(r) == ID );
190
191  float aa=nf(a).F()+1.0;
192  if (aa<0.0) aa=-aa;
193  return (aa<nrEps);
194}
195
196number nrDiv (number a,number b, const coeffs r)
197{
198  assume( getCoeffType(r) == ID );
199
200  float n = nf(b).F();
201  if (n == 0.0)
202  {
203    WerrorS(nDivBy0);
204    return nf((float)0.0).N();
205  }
206  else
207    return nf(nf(a).F() / n).N();
208}
209
210number  nrInvers (number c, const coeffs r)
211{
212  assume( getCoeffType(r) == ID );
213
214  float n = nf(c).F();
215  if (n == 0.0)
216  {
217    WerrorS(nDivBy0);
218    return nf((float)0.0).N();
219  }
220  return nf(1.0 / n).N();
221}
222
223number nrNeg (number c, const coeffs r)
224{
225  assume( getCoeffType(r) == ID );
226
227  return nf(-nf(c).F()).N();
228}
229
230BOOLEAN nrGreater (number a,number b, const coeffs r)
231{
232  assume( getCoeffType(r) == ID );
233
234  return nf(a).F() > nf(b).F();
235}
236
237BOOLEAN nrEqual (number a,number b, const coeffs r)
238{
239  assume( getCoeffType(r) == ID );
240
241  number x = nrSub(a,b,r);
242  return nf(x).F() == nf((float)0.0).F();
243}
244
245void nrWrite (number &a, const coeffs r)
246{
247  assume( getCoeffType(r) == ID );
248
249  StringAppend("%9.3e", nf(a).F());
250}
251
252void nrPower (number a, int i, number * result, const coeffs r)
253{
254  assume( getCoeffType(r) == ID );
255
256  if (i==0)
257  {
258    *result = nf(nf(1.0).F()).N();
259    return;
260  }
261  if (i==1)
262  {
263    *result = nf(nf(a).F()).N();
264    return;
265  }
266  nrPower(a,i-1,result,r);
267  *result = nf(nf(a).F() * nf(*result).F()).N();
268}
269
270namespace {
271static const char* nrEatr(const char *s, float *r)
272{
273  int i;
274
275  if    (*s >= '0' && *s <= '9')
276  {
277    *r = 0.0;
278    do
279    {
280      *r *= 10.0;
281      i = *s++ - '0';
282      *r += (float)i;
283    }
284    while (*s >= '0' && *s <= '9');
285  }
286  else *r = 1.0;
287  return s;
288}
289};
290
291const char * nrRead (const char *s, number *a, const coeffs r)
292{
293
294  assume( getCoeffType(r) == ID );
295
296  static const char *nIllegalChar="illegal character in number";
297
298  const char *t;
299  const char *start=s;
300  float z1,z2;
301  float n=1.0;
302
303  s = nrEatr(s, &z1);
304  if (*s == '/')
305  {
306    if (s==start) { WerrorS(nIllegalChar);return s; }
307    s++;
308    s = nrEatr(s, &z2);
309    if (z2==0.0)
310      WerrorS(nDivBy0);
311    else
312      z1 /= z2;
313  }
314  else if (*s =='.')
315  {
316    if (s==start) { WerrorS(nIllegalChar);return s; }
317    s++;
318    t = s;
319    while (*t >= '0' && *t <= '9')
320    {
321      t++;
322      n *= 10.0;
323    }
324    s = nrEatr(s, &z2);
325    z1 = (z1*n + z2) / n;
326    if (*s=='e')
327    {
328      int e=0; /* exponent */
329      int si=1;/* sign of exponent */
330      s++;
331      if (*s=='+') s++;
332      else if (*s=='-') {s++; si=-1; }
333      while (*s >= '0' && *s <= '9')
334      {
335        e=e*10+(*s)-'0';
336        s++;
337      }
338      if (si==1)
339      {
340        while (e>0) {z1*=10.0; e--; }
341      }
342      else
343      {
344        while (e>0) {z1/=10.0; e--; }
345      }
346    }
347  }
348  *a = nf(z1).N();
349  return s;
350}
351
352
353// the last used charcteristic
354// int nrGetChar(){ return 0; }
355
356
357#ifdef LDEBUG
358/*2
359* test valid numbers: not implemented yet
360*/
361BOOLEAN  nrDBTest(number a, const char *f, const int l, const coeffs r);
362{
363  assume( getCoeffType(r) == ID );
364
365  return TRUE;
366}
367#endif
368
369static number nrMapP(number from, const coeffs aRing, const coeffs r)
370{
371  assume( getCoeffType(r) == ID );
372  assume( getCoeffType(aRing) ==  n_Zp );
373 
374  int i = (int)((long)from);
375  float f = (float)i;
376  return nf(f).N();
377}
378
379static number nrMapLongR(number from, const coeffs aRing, const coeffs r)
380{
381  assume( getCoeffType(r) == ID );
382  assume( getCoeffType(aRing) == n_long_R );
383
384  float t =(float)mpf_get_d((mpf_srcptr)from);
385  return nf(t).N();
386}
387
388static number nrMapC(number from, const coeffs aRing, const coeffs r)
389{ 
390  assume( getCoeffType(r) == ID );
391  assume( getCoeffType(aRing) == n_long_C );
392 
393  gmp_float h = ((gmp_complex*)from)->real();
394  float t =(float)mpf_get_d((mpf_srcptr)&h);
395  return nf(t).N();
396}
397
398
399number nrMapQ(number from, const coeffs aRing, const coeffs r)
400{
401/* in longrat.h
402#define SR_INT    1
403#define mpz_size1(A) (ABS((A)->_mp_size))
404*/
405#define SR_HDL(A) ((long)(A))
406#define mpz_isNeg(A) ((A)->_mp_size<0)
407#define mpz_limb_size(A) ((A)->_mp_size)
408#define mpz_limb_d(A) ((A)->_mp_d)
409#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
410#define IS_INT(A) ((A)->s==3)
411#define IS_IMM(A) (SR_HDL(A)&SR_INT)
412#define GET_NOM(A) ((A)->z)
413#define GET_DENOM(A) ((A)->n)
414#define MPZ_INIT mpz_init
415#define MPZ_CLEAR mpz_clear
416
417  assume( getCoeffType(r) == ID );
418  assume( getCoeffType(aRing) == n_Q );
419
420  mpz_t h;
421  mpz_ptr g,z,n;
422  int i,j,t,s;
423  float ba,rr,rn,y;
424
425  if (IS_IMM(from))
426    return nf((float)nlInt(from,NULL /* dummy for nlInt*/)).N();
427  z=GET_NOM(from);
428  s=0X10000;
429  ba=(float)s;
430  ba*=ba;
431  rr=0.0;
432  i=mpz_size1(z);
433  if(IS_INT(from))
434  {
435    if(i>4)
436    {
437      WerrorS("float overflow");
438      return nf(rr).N();
439    }
440    i--;
441    rr=(float)mpz_limb_d(z)[i];
442    while(i>0)
443    {
444      i--;
445      y=(float)mpz_limb_d(z)[i];
446      rr=rr*ba+y;
447    }
448    if(mpz_isNeg(z))
449      rr=-rr;
450    return nf(rr).N();
451  }
452  n=GET_DENOM(from);
453  j=s=mpz_limb_size(n);
454  if(j>i)
455  {
456    g=n; n=z; z=g;
457    t=j; j=i; i=t;
458  }
459  t=i-j;
460  if(t>4)
461  {
462    if(j==s)
463      WerrorS("float overflow");
464    return nf(rr).N();
465  }
466  if(t>1)
467  {
468    g=h;
469    MPZ_INIT(g);
470    MPZ_DIV(g,z,n);
471    t=mpz_size1(g);
472    if(t>4)
473    {
474      MPZ_CLEAR(g);
475      if(j==s)
476        WerrorS("float overflow");
477      return nf(rr).N();
478    }
479    t--;
480    rr=(float)mpz_limb_d(g)[t];
481    while(t)
482    {
483      t--;
484      y=(float)mpz_limb_d(g)[t];
485      rr=rr*ba+y;
486    }
487    MPZ_CLEAR(g);
488    if(j!=s)
489      rr=1.0/rr;
490    if(mpz_isNeg(z))
491      rr=-rr;
492    return nf(rr).N();
493  }
494  rn=(float)mpz_limb_d(n)[j-1];
495  rr=(float)mpz_limb_d(z)[i-1];
496  if(j>1)
497  {
498    rn=rn*ba+(float)mpz_limb_d(n)[j-2];
499    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
500    i--;
501  }
502  if(t!=0)
503    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
504  if(j==s)
505    rr=rr/rn;
506  else
507    rr=rn/rr;
508  if(mpz_isNeg(z))
509    rr=-rr;
510  return nf(rr).N();
511}
512
513
514nMapFunc nrSetMap(const coeffs src, const coeffs dst)
515{
516  assume( getCoeffType(dst) == ID );
517
518  if (nField_is_Q(src))
519  {
520    return nrMapQ;
521  }
522  if (nField_is_long_R(src))
523  {
524    return nrMapLongR;
525  }
526  if (nField_is_R(src))
527  {
528    return ndCopyMap;
529  }
530  if(nField_is_Zp(src))
531  {
532    return nrMapP;
533  }
534  if (nField_is_long_C(src))
535  {
536    return nrMapC;
537  }
538  return NULL;
539}
Note: See TracBrowser for help on using the repository browser.