1 // cl_LF implementation
9 #include "cl_offsetof.h"
12 extern cl_class cl_class_lfloat;
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)
22 cl_heap_lfloat* p = (cl_heap_lfloat*) cl_malloc_hook(offsetofa(cl_heap_lfloat,data)+sizeof(uintD)*len);
24 p->type = &cl_class_lfloat;
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) {}
35 // Both work, but the first definition results in less compiler-generated
38 #define Lfloat cl_heap_lfloat*
43 // Pointers to the mantissa.
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); }
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); }
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; \
69 { mantlen_zuweisung _x->len; zero_statement } /* e=0 -> Zahl 0.0 */\
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))); \
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)
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
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)
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));
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)
107 return encode_LF1s(0,len);
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)
120 var Lfloat erg = allocate_lfloat(mantlen,uexp,sign); /* Exponent */
121 copy_loop_msp(mantMSDptr,arrayMSDptr(TheLfloat(erg)->data,mantlen),mantlen); /* Mantisse übertragen */
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)
135 return encode_LFu(sign,LF_exp_mid+(uintL)exp,mantMSDptr,mantlen);
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)
149 #endif /* _CL_LF_IMPL_H */