]> www.ginac.de Git - cln.git/blob - src/float/conv/cl_LF_to_double.cc
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / float / conv / cl_LF_to_double.cc
1 // cl_LF_to_double().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/lfloat.h"
8
9
10 // Implementation.
11
12 #include "cl_LF.h"
13 #include "cl_LF_impl.h"
14 #include "cl_DF.h"
15 #include "cl_DS.h"
16
17 namespace cln {
18
19 double double_approx (const cl_LF& x)
20 {
21         // x entpacken:
22         var cl_signean sign;
23         var sintL exp;
24         var uintD* ptr;
25         var uintC len;
26         LF_decode(x, { return 0.0; }, sign=,exp=,ptr=,len=,);
27         // intDsize*len-DF_mant_len-1 Bits der Mantisse wegrunden:
28         // erste k := ceiling(DF_mant_len+2,intDsize) Digits nach manthi,mantlo holen:
29         var const int shiftcount = ceiling(DF_mant_len+2,intDsize)*intDsize-(DF_mant_len+1);
30         union { dfloat eksplicit; double machine_double; } u;
31         #if (cl_word_size==64)
32         var uint64 mant = get_max64_Dptr(DF_mant_len+2,ptr);
33         ptr = ptr mspop ceiling(DF_mant_len+2,intDsize);
34         if ( ((mant & bit(shiftcount-1)) ==0) // Bit 10 war 0 -> abrunden
35              || ( ((mant & (bit(shiftcount-1)-1)) ==0) // war 1, Bits 9..0 >0 -> aufrunden
36                   && !test_loop_msp(ptr,len-ceiling(DF_mant_len+2,intDsize)) // weitere Bits /=0 -> aufrunden
37                   // round-to-even
38                   && ((mant & bit(shiftcount)) ==0)
39            )    )
40           // abrunden
41           { mant = mant >> shiftcount; }
42           else
43           // aufrunden
44           { mant = mant >> shiftcount;
45             mant = mant+1;
46             if (mant >= bit(DF_mant_len+1))
47               // Überlauf durchs Runden
48               { mant = mant>>1; exp = exp+1; } // Mantisse rechts schieben
49           }
50         if (exp > (sintL)(DF_exp_high-DF_exp_mid))
51           { u.eksplicit =
52                 ((sint64)sign & bit(63))
53               | ((uint64)(bit(DF_exp_len)-1) << DF_mant_len); // Infinity
54           }
55         else
56         if (exp < (sintL)(DF_exp_low-DF_exp_mid))
57           { u.eksplicit = ((sint64)sign & bit(63)); } // 0.0
58         else
59           { u.eksplicit =
60                 ((sint64)sign & bit(63))                  /* Vorzeichen */
61               | ((uint64)(exp+DF_exp_mid) << DF_mant_len) /* Exponent   */
62               | ((uint64)mant & (bit(DF_mant_len)-1));    /* Mantisse   */
63           }
64         #else
65         var uint32 manthi = get_max32_Dptr(DF_mant_len+2-32,ptr);
66         var uint32 mantlo = get_32_Dptr(ptr mspop ceiling(DF_mant_len+2-32,intDsize));
67         ptr = ptr mspop ceiling(DF_mant_len+2,intDsize);
68         if ( ((mantlo & bit(shiftcount-1)) ==0) // Bit 10 war 0 -> abrunden
69              || ( ((mantlo & (bit(shiftcount-1)-1)) ==0) // war 1, Bits 9..0 >0 -> aufrunden
70                   && !test_loop_msp(ptr,len-ceiling(DF_mant_len+2,intDsize)) // weitere Bits /=0 -> aufrunden
71                   // round-to-even
72                   && ((mantlo & bit(shiftcount)) ==0)
73            )    )
74           // abrunden
75           { mantlo = (manthi << (32-shiftcount)) | (mantlo >> shiftcount);
76             manthi = manthi >> shiftcount;
77           }
78           else
79           // aufrunden
80           { mantlo = (manthi << (32-shiftcount)) | (mantlo >> shiftcount);
81             manthi = manthi >> shiftcount;
82             mantlo = mantlo+1;
83             if (mantlo==0)
84               { manthi = manthi+1;
85                 if (manthi >= bit(DF_mant_len+1-32))
86                   // Überlauf durchs Runden
87                   { manthi = manthi>>1; exp = exp+1; } // Mantisse rechts schieben
88           }   }
89         if (exp > (sintL)(DF_exp_high-DF_exp_mid))
90           { u.eksplicit.semhi =
91                 ((sint32)sign & bit(31))
92               | ((uint32)(bit(DF_exp_len)-1) << (DF_mant_len-32)); // Infinity
93             u.eksplicit.mlo = 0;
94           }
95         else
96         if (exp < (sintL)(DF_exp_low-DF_exp_mid))
97           { u.eksplicit.semhi = ((sint32)sign & bit(31)); // 0.0
98             u.eksplicit.mlo = 0;
99           }
100         else
101           { u.eksplicit.semhi =
102                 ((sint32)sign & bit(31))                       /* Vorzeichen */
103               | ((uint32)(exp+DF_exp_mid) << (DF_mant_len-32)) /* Exponent   */
104               | ((uint32)manthi & (bit(DF_mant_len-32)-1));    /* Mantisse   */
105             u.eksplicit.mlo = mantlo;
106           }
107         #endif
108         return u.machine_double;
109 }
110
111 }  // namespace cln