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