]> www.ginac.de Git - cln.git/blob - src/float/lfloat/misc/cl_LF_shortenrel.cc
Use paths relative the `src' directory in the #include directives.
[cln.git] / src / float / lfloat / misc / cl_LF_shortenrel.cc
1 // cl_LF_shortenrelative().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "float/lfloat/cl_LF.h"
8
9
10 // Implementation.
11
12 #include "cln/exception.h"
13
14 #include "base/cl_inline2.h"
15 #include "float/lfloat/misc/cl_LF_precision.cc"
16 #include "base/cl_inline.h"
17 #include "float/lfloat/misc/cl_LF_exponent.cc"
18
19 namespace cln {
20
21 const cl_LF cl_LF_shortenrelative (const cl_LF& x, const cl_LF& y)
22 {
23         // Methode:
24         // x = 0.0 -> Precision egal, return x.
25         // ex := float_exponent(x), ey := float_exponent(y).
26         // dx := float_digits(x), dy := float_digits(y).
27         // 1 ulp(x) = 2^(ex-dx), 1 ulp(y) = 2^(ey-dy).
28         // Falls ex-dx < ey-dy, x von Precision dx auf dy-ey+ex verkürzen.
29         var sintE ey = float_exponent_inline(y);
30         var sintC dy = float_precision_inline(y);
31         if (dy==0) // zerop(y) ?
32                 throw runtime_exception();
33         var sintE ex = float_exponent_inline(x);
34         var sintC dx = float_precision_inline(x);
35         if (dx==0) // zerop(x) ?
36                 return x;
37         var sintE d = ex - ey;
38         if (ex>=0 && ey<0 && d<0) // d overflow?
39                 return x;
40         if (ex<0 && ey>=0 && d>=0) // d underflow?
41                 return LF_to_LF(x,LF_minlen);
42         if (d >= dx - dy)
43                 return x;
44         var uintC new_dx = dy + d;
45         var uintC len = ceiling(new_dx,intDsize);
46         if (len < LF_minlen)
47                 len = LF_minlen;
48         if (intDsize*len < (uintC)dx)
49                 return shorten(x,len);
50         else
51                 return x;
52 }
53
54 }  // namespace cln