source: git/kernel/shortfl.cc @ cdec33

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