source: git/libpolys/coeffs/shortfl.cc @ 7089a9

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