source: git/libpolys/coeffs/shortfl.cc @ 236a4c

spielwiese
Last change on this file since 236a4c was 236a4c, checked in by Yue Ren <ren@…>, 10 years ago
fix: number to float conversion on 64bit machines
  • Property mode set to 100644
File size: 9.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT:
7*/
8#include <iostream>
9#include <coeffs/shortfl.h>
10
11#include <string.h>
12#include <math.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 IS_INT(A) ((A)->s==3)
410#define IS_IMM(A) (SR_HDL(A)&SR_INT)
411#define GET_NOM(A) ((A)->z)
412#define GET_DENOM(A) ((A)->n)
413
414  assume( getCoeffType(r) == ID );
415  assume( getCoeffType(aRing) == n_Q );
416
417  if (IS_IMM(from))
418    return nf((float)nlInt(from,NULL /* dummy for nlInt*/)).N();
419
420  /* read out the enumerator */
421  mpz_ptr z=GET_NOM(from);
422  if(mpz_size1(z)>4)
423  {
424    WerrorS("float overflow");
425    return nf(0.0).N();
426  }
427  mpf_t e;
428  mpf_init(e);
429  mpf_set_z(e,z);
430
431  /* if number was an integer, we are done*/
432  if(IS_INT(from))
433  {
434    double basis;
435    signed long int exp;
436    basis = mpf_get_d_2exp(&exp, e);
437    float f = ldexp(basis,exp);
438    mpf_clear(e);
439    return nf(f).N();
440  }
441
442  /* else read out the denominator */
443  mpz_ptr n = GET_DENOM(from);
444  if(mpz_size1(n)>4)
445  {
446    WerrorS("float overflow");
447    mpf_clear(e);
448    return nf(0.0).N();
449  }
450  mpf_t d;
451  mpf_init(d);
452  mpf_set_z(d,n);
453
454  /* and compute the quotient */
455  mpf_t q;
456  mpf_init(q);
457  mpf_div(q,e,d);
458
459  double basis;
460  signed long int exp;
461  basis = mpf_get_d_2exp(&exp, q);
462  float f = ldexp(basis,exp);
463  mpf_clear(e);
464  mpf_clear(d);
465  mpf_clear(q);
466  return nf(f).N();
467}
468
469nMapFunc nrSetMap(const coeffs src, const coeffs dst)
470{
471  assume( getCoeffType(dst) == ID );
472
473  if (nCoeff_is_Q(src))
474  {
475    return nrMapQ;
476  }
477  if (nCoeff_is_long_R(src))
478  {
479    return nrMapLongR;
480  }
481  if (nCoeff_is_R(src))
482  {
483    return ndCopyMap;
484  }
485  if(nCoeff_is_Zp(src))
486  {
487    return nrMapP;
488  }
489  if (nCoeff_is_long_C(src))
490  {
491    return nrMapC;
492  }
493  return NULL;
494}
495
496BOOLEAN nrInitChar(coeffs n, void* p)
497{
498  assume( getCoeffType(n) == ID );
499
500  assume( p == NULL );
501
502  n->cfKillChar = ndKillChar; /* dummy */
503  n->ch = 0;
504
505  n->cfInit = nrInit;
506  n->cfInt  = nrInt;
507  n->cfAdd   = nrAdd;
508  n->cfSub   = nrSub;
509  n->cfMult  = nrMult;
510  n->cfDiv   = nrDiv;
511  n->cfExactDiv= nrDiv;
512  n->cfNeg   = nrNeg;
513  n->cfInvers= nrInvers;
514  n->cfCopy  = ndCopy;
515  n->cfGreater = nrGreater;
516  n->cfEqual = nrEqual;
517  n->cfIsZero = nrIsZero;
518  n->cfIsOne = nrIsOne;
519  n->cfIsMOne = nrIsMOne;
520  n->cfGreaterZero = nrGreaterZero;
521  n->cfWriteLong = nrWrite;
522  n->cfRead = nrRead;
523  n->cfPower = nrPower;
524  n->cfSetMap = nrSetMap;
525  n->cfCoeffWrite  = nrCoeffWrite;
526  n->cfInit_bigint = nrMapQ;
527
528    /* nName= ndName; */
529    /*nSize  = ndSize;*/
530#ifdef LDEBUG
531  n->cfDBTest=ndDBTest; // not yet implemented: nrDBTest;
532#endif
533
534  n->nCoeffIsEqual = ndCoeffIsEqual;
535
536  n->float_len = SHORT_REAL_LENGTH;
537  n->float_len2 = SHORT_REAL_LENGTH;
538
539  // TODO: Any variables?
540  return FALSE;
541}
Note: See TracBrowser for help on using the repository browser.