1 // cl_LF implementation
6 #include "cln/number.h"
7 #include "float/lfloat/cl_LF.h"
8 #include "cln/malloc.h"
9 #include "base/cl_offsetof.h"
10 #include "base/digitseq/cl_DS.h"
14 extern cl_class cl_class_lfloat;
16 // Builds a long-float, without filling the mantissa.
17 // allocate_lfloat(len,expo,sign)
18 // > uintC len: length of mantissa (in digits)
19 // > uintE 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, uintE expo, cl_signean sign)
24 cl_heap_lfloat* p = (cl_heap_lfloat*) malloc_hook(offsetofa(cl_heap_lfloat,data)+sizeof(uintD)*len);
26 p->type = &cl_class_lfloat;
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) {}
37 // Both work, but the first definition results in less compiler-generated
40 #define Lfloat cl_heap_lfloat*
45 // Pointers to the mantissa.
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); }
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); }
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 // sintE 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 uintE uexp = _x->expo; \
71 { cl_unused (mantlen_zuweisung _x->len); zero_statement } /* e=0 -> Zahl 0.0 */\
73 { exp_zuweisung (sintE)(uexp - LF_exp_mid); /* Exponent */ \
74 sign_zuweisung _x->sign; /* Vorzeichen */\
75 cl_unused (mantMSDptr_zuweisung arrayMSDptr(_x->data, (uintP)(mantlen_zuweisung _x->len))); /* Mantissen-UDS */\
76 cl_unused (mantLSDptr_zuweisung arrayLSDptr(_x->data, (uintP)(mantlen_zuweisung _x->len))); \
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)
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
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)
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));
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)
109 return encode_LF1s(0,len);
112 // Einpacken eines Long-Float:
113 // encode_LFu(sign,uexp,mantMSDptr,mantlen) liefert ein Long-Float
114 // > cl_signean sign: Vorzeichen
115 // > uintE 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, uintE uexp, const uintD* mantMSDptr, uintC mantlen)
122 var Lfloat erg = allocate_lfloat(mantlen,uexp,sign); /* Exponent */
123 copy_loop_msp(mantMSDptr,arrayMSDptr(TheLfloat(erg)->data,mantlen),mantlen); /* Mantisse übertragen */
127 // Einpacken eines Long-Float:
128 // encode_LF(sign,exp,mantMSDptr,mantlen) liefert ein Long-Float
129 // > cl_signean sign: Vorzeichen
130 // > sintE 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, sintE exp, const uintD* mantMSDptr, uintC mantlen)
137 return encode_LFu(sign,LF_exp_mid+(uintE)exp,mantMSDptr,mantlen);
140 // Einpacken eines Long-Float:
141 // encode_LF_array(sign,exp,mantarr,mantlen) liefert ein Long-Float
142 // > cl_signean sign: Vorzeichen
143 // > sintE 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)
153 #endif /* _CL_LF_IMPL_H */