13 #include "cl_LF_impl.h"
17 const cl_LF operator* (const cl_LF& x1, const cl_LF& x2)
20 // Falls x1=0.0 oder x2=0.0 -> Ergebnis 0.0
21 // Sonst: Ergebnis-Vorzeichen = VZ von x1 xor VZ von x2.
22 // Ergebnis-Exponent = Summe der Exponenten von x1 und x2.
23 // Produkt der Mantissen bilden (2n Digits).
24 // Falls das führende Bit =0 ist: Mantissenprodukt um 1 Bit nach links
25 // schieben (die vorderen n+1 Digits genügen)
26 // und Exponent decrementieren.
27 // Runden auf n Digits liefert die Ergebnis-Mantisse.
28 var uintC len1 = TheLfloat(x1)->len;
29 var uintC len2 = TheLfloat(x2)->len;
30 var uintC len = (len1 < len2 ? len1 : len2); // min. Länge n von x1 und x2
31 var uintL uexp1 = TheLfloat(x1)->expo;
32 if (uexp1==0) // x1=0.0 -> Ergebnis 0.0
33 { if (len < len1) return shorten(x1,len); else return x1; }
34 var uintL uexp2 = TheLfloat(x2)->expo;
35 if (uexp2==0) // x2=0.0 -> Ergebnis 0.0
36 { if (len < len2) return shorten(x2,len); else return x2; }
37 // Exponenten addieren:
38 // (uexp1-LF_exp_mid) + (uexp2-LF_exp_mid) = (uexp1+uexp2-LF_exp_mid)-LF_exp_mid
39 uexp1 = uexp1 + uexp2;
42 { if (uexp1 < LF_exp_mid+LF_exp_low)
43 { if (underflow_allowed())
44 { cl_error_floating_point_underflow(); }
46 { return encode_LF0(len); } // Ergebnis 0.0
50 { if (uexp1 > (uintL)(LF_exp_mid+LF_exp_high+1)) { cl_error_floating_point_overflow(); } }
51 uexp1 = uexp1 - LF_exp_mid;
52 // Nun ist LF_exp_low <= uexp1 <= LF_exp_high+1.
53 // neues Long-Float allozieren:
54 var Lfloat y = allocate_lfloat(len,uexp1,
55 TheLfloat(x1)->sign ^ TheLfloat(x2)->sign // Vorzeichen kombinieren
58 var const uintD* x1_LSDptr = arrayLSDptr(TheLfloat(x1)->data,len1);
59 var const uintD* x2_LSDptr = arrayLSDptr(TheLfloat(x2)->data,len2);
60 #ifndef CL_LF_PEDANTIC
62 { x1_LSDptr = x1_LSDptr lspop (len1-(len2+1)); len1 = len2+1; }
64 { x2_LSDptr = x2_LSDptr lspop (len2-(len1+1)); len2 = len1+1; }
68 UDS_UDS_mul_UDS(len1,x1_LSDptr,
71 {var uintD* midptr = MSDptr mspop len; // Pointer in die Mitte der len1+len2 Digits
72 if ((sintD)mspref(MSDptr,0) >= 0) // führendes Bit abtesten
73 { // erste n+1 Digits um 1 Bit nach links schieben:
74 shift1left_loop_lsp(midptr mspop 1,len+1);
75 // Exponenten decrementieren:
76 if ((TheLfloat(y)->expo)-- == LF_exp_low-1)
77 { if (underflow_allowed())
78 { cl_error_floating_point_underflow(); }
80 { return encode_LF0(len); } // Ergebnis 0.0
83 // erste Hälfte des Mantissenprodukts übertragen:
84 {var uintD* y_mantMSDptr = arrayMSDptr(TheLfloat(y)->data,len);
85 var uintD* y_mantLSDptr = copy_loop_msp(MSDptr,y_mantMSDptr,len);
87 if ( ((sintD)mspref(midptr,0) >= 0) // nächstes Bit =0 -> abrunden
88 || ( ((mspref(midptr,0) & ((uintD)bit(intDsize-1)-1)) ==0) // Bit =1, weitere Bits >0 -> aufrunden
89 && !test_loop_msp(midptr mspop 1,len1+len2-len-1)
91 && ((lspref(midptr,0) & bit(0)) ==0)
97 { if ( inc_loop_lsp(y_mantLSDptr,len) )
98 { // Übertrag durchs Aufrunden (kann nur auftreten,
99 // wenn vorhin um 1 Bit nach links geschoben wurde)
100 mspref(y_mantMSDptr,0) = bit(intDsize-1); // Mantisse := 10...0
101 (TheLfloat(y)->expo)++; // Exponent wieder zurück-erhöhen
103 // LF_exp_low <= exp <= LF_exp_high sicherstellen:
104 if (TheLfloat(y)->expo == LF_exp_high+1) { cl_error_floating_point_overflow(); }
108 // Bit complexity (N = max(length(x1),length(x2))): O(M(N)).