]> www.ginac.de Git - cln.git/blob - src/float/lfloat/cl_LF_impl.h
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / float / lfloat / cl_LF_impl.h
1 // cl_LF implementation
2
3 #ifndef _CL_LF_IMPL_H
4 #define _CL_LF_IMPL_H
5
6 #include "cln/number.h"
7 #include "cl_LF.h"
8 #include "cln/malloc.h"
9 #include "cl_offsetof.h"
10 #include "cl_DS.h"
11
12 namespace cln {
13
14 extern cl_class cl_class_lfloat;
15
16 // Builds a long-float, without filling the mantissa.
17 // allocate_lfloat(len,expo,sign)
18 // > uintC len: length of mantissa (in digits)
19 // > uint32 expo: exponent
20 // > cl_signean sign: sign (0 = +, -1 = -)
21 // The long-float is only complete when the mantissa has been filled in!
22 inline cl_heap_lfloat* allocate_lfloat (uintC len, uint32 expo, cl_signean sign)
23 {
24         cl_heap_lfloat* p = (cl_heap_lfloat*) malloc_hook(offsetofa(cl_heap_lfloat,data)+sizeof(uintD)*len);
25         p->refcount = 1;
26         p->type = &cl_class_lfloat;
27         p->len = len;
28         p->sign = sign;
29         p->expo = expo;
30         return p;
31 }
32
33 // Private constructor.
34 // ptr should be the result of some allocate_lfloat() call.
35 inline cl_LF::cl_LF (cl_heap_lfloat* ptr) : cl_F ((cl_private_thing) ptr) {}
36
37 // Both work, but the first definition results in less compiler-generated
38 // temporaries.
39 #if 1
40   #define Lfloat  cl_heap_lfloat*
41 #else
42   #define Lfloat  cl_LF
43 #endif
44
45 // Pointers to the mantissa.
46 #if 1
47   inline const uintD* LF_MSDptr (Lfloat lf)
48     { return (const uintD*) arrayMSDptr(lf->data,lf->len); }
49   inline const uintD* LF_LSDptr (Lfloat lf)
50     { return (const uintD*) arrayLSDptr(lf->data,lf->len); }
51 #endif
52   inline const uintD* LF_MSDptr (const cl_LF& obj)
53     { var cl_heap_lfloat* lf = TheLfloat(obj); return (const uintD*) arrayMSDptr(lf->data,lf->len); }
54   inline const uintD* LF_LSDptr (const cl_LF& obj)
55     { var cl_heap_lfloat* lf = TheLfloat(obj); return (const uintD*) arrayLSDptr(lf->data,lf->len); }
56
57
58 // Entpacken eines Long-Float:
59 // LF_decode(obj, zero_statement, sign=,exp=,mantMSDptr=,mantlen=,mantLSDptr=);
60 // zerlegt ein Long-Float obj.
61 // Ist obj=0.0, wird zero_statement ausgeführt.
62 // Sonst: cl_signean sign = Vorzeichen (0 = +, -1 = -),
63 //        sintL exp = Exponent (vorzeichenbehaftet),
64 //        UDS mantMSDptr/mantlen/mantLSDptr = Mantisse
65 //          (>= 2^(intDsize*mantlen-1), < 2^(intDsize*mantlen)),
66 //          mit mantlen>=LF_minlen.
67   #define LF_decode(obj, zero_statement, sign_zuweisung,exp_zuweisung,mantMSDptr_zuweisung,mantlen_zuweisung,mantLSDptr_zuweisung)  \
68     { var Lfloat _x = TheLfloat(obj);                                   \
69       var uintL uexp = _x->expo;                                        \
70       if (uexp==0)                                                      \
71         { mantlen_zuweisung _x->len; zero_statement } /* e=0 -> Zahl 0.0 */\
72         else                                                            \
73         { exp_zuweisung (sintL)(uexp - LF_exp_mid);     /* Exponent */  \
74           sign_zuweisung _x->sign;                      /* Vorzeichen */\
75           unused (mantMSDptr_zuweisung arrayMSDptr(_x->data, (uintP)(mantlen_zuweisung _x->len))); /* Mantissen-UDS */\
76           unused (mantLSDptr_zuweisung arrayLSDptr(_x->data, (uintP)(mantlen_zuweisung _x->len))); \
77     }   }
78
79 // Einpacken eines Long-Float:
80 // encode_LF0(len) liefert ein Long-Float 0.0 mit len Digits.
81 // > uintC len: Anzahl der Digits
82 // < cl_LF ergebnis: neues Long-Float 0.0 mit len Digits
83 inline const cl_LF encode_LF0 (uintC len)
84 {
85         var Lfloat erg = allocate_lfloat(len,0,0); // Exponent 0, Vorzeichen +
86         DS_clear_loop(arrayMSDptr(TheLfloat(erg)->data,len),len,arrayLSDptr(TheLfloat(erg)->data,len)); // Mantisse := 0
87         return erg;
88 }
89
90 // Einpacken eines Long-Float:
91 // encode_LF1s(sign,len) liefert ein Long-Float +-1.0 mit len Digits.
92 // > cl_signean sign: Vorzeichen
93 // > uintC len: Anzahl der Digits
94 // < cl_LF ergebnis: neues Long-Float +1.0 oder -1.0 mit len Digits
95 inline const cl_LF encode_LF1s (cl_signean sign, uintC len)
96 {
97         var Lfloat erg = allocate_lfloat(len,LF_exp_mid+1,sign); // Exponent 1
98         mspref(arrayMSDptr(TheLfloat(erg)->data,len),0) = bit(intDsize-1); // Mantisse := 2^(intDsize*len-1)
99         DS_clear_loop(arrayMSDptr(TheLfloat(erg)->data,len) mspop 1,len-1,arrayLSDptr(TheLfloat(erg)->data,len));
100         return erg;
101 }
102
103 // Einpacken eines Long-Float:
104 // encode_LF1(len) liefert ein Long-Float 1.0 mit len Digits.
105 // > uintC len: Anzahl der Digits
106 // < cl_LF ergebnis: neues Long-Float 1.0 mit len Digits
107 inline const cl_LF encode_LF1 (uintC len)
108 {
109         return encode_LF1s(0,len);
110 }
111
112 // Einpacken eines Long-Float:
113 // encode_LFu(sign,uexp,mantMSDptr,mantlen) liefert ein Long-Float
114 // > cl_signean sign: Vorzeichen
115 // > uintL exp: Exponent + LF_exp_mid
116 // > uintD* mantMSDptr: Pointer auf eine NUDS mit gesetztem höchstem Bit
117 // > uintC mantlen: Anzahl der Digits, >= LF_minlen
118 // < cl_LF erg: neues Long-Float mit der UDS mantMSDptr/mantlen/.. als Mantisse
119 // Der Exponent wird nicht auf Überlauf/Unterlauf getestet.
120 inline const cl_LF encode_LFu (cl_signean sign, uintL uexp, const uintD* mantMSDptr, uintC mantlen)
121 {
122         var Lfloat erg = allocate_lfloat(mantlen,uexp,sign); /* Exponent */
123         copy_loop_msp(mantMSDptr,arrayMSDptr(TheLfloat(erg)->data,mantlen),mantlen); /* Mantisse übertragen */
124         return erg;
125 }
126
127 // Einpacken eines Long-Float:
128 // encode_LF(sign,exp,mantMSDptr,mantlen) liefert ein Long-Float
129 // > cl_signean sign: Vorzeichen
130 // > sintL exp: Exponent
131 // > uintD* mantMSDptr: Pointer auf eine NUDS mit gesetztem höchstem Bit
132 // > uintC mantlen: Anzahl der Digits, >= LF_minlen
133 // < cl_LF erg: neues Long-Float mit der UDS mantMSDptr/mantlen/.. als Mantisse
134 // Der Exponent wird nicht auf Überlauf/Unterlauf getestet.
135 inline const cl_LF encode_LF (cl_signean sign, sintL exp, const uintD* mantMSDptr, uintC mantlen)
136 {
137         return encode_LFu(sign,LF_exp_mid+(uintL)exp,mantMSDptr,mantlen);
138 }
139
140 // Einpacken eines Long-Float:
141 // encode_LF_array(sign,exp,mantarr,mantlen) liefert ein Long-Float
142 // > cl_signean sign: Vorzeichen
143 // > sintL exp: Exponent
144 // > uintD mantarr[]: NUDS mit gesetztem höchstem Bit
145 // > uintC mantlen: Anzahl der Digits, >= LF_minlen
146 // < cl_LF erg: neues Long-Float mit der UDS mantarr[] als Mantisse
147 // Der Exponent wird nicht auf Überlauf/Unterlauf getestet.
148 #define encode_LF_array(sign,exp,mantarr,mantlen)  \
149   encode_LF(sign,exp,arrayMSDptr(mantarr,mantlen),mantlen)
150
151 }  // namespace cln
152
153 #endif /* _CL_LF_IMPL_H */