7 #include "cln/integer.h"
17 const cl_I operator+ (const cl_I& x, const cl_I& y)
21 // y Fixnum -> beide direkt addieren, mit L_to_I beenden
22 // y Bignum -> falls x=0, y; sonst beide zu DS machen, addieren.
24 // y Fixnum -> falls y=0, x; sonst beide zu DS machen, addieren.
25 // y Bignum -> beide zu DS machen, addieren.
29 // MSDptr/len/LSDptr bilden die DS des Ergebnisses.
34 #if (cl_value_len < intVsize)
35 return V_to_I( FN_to_V(x) + FN_to_V(y) ); // als intVsize-Bit-Zahlen addieren
36 #elif (cl_word_size==64)
37 return Q_to_I( FN_to_Q(x) + FN_to_Q(y) ); // als 64-Bit-Zahlen addieren
38 #elif (intVsize==32) // && (cl_value_len == intVsize)
39 var sint32 xhi = sign_of(FN_to_V(x));
40 var uint32 xlo = FN_to_V(x);
41 var sint32 yhi = sign_of(FN_to_V(y));
42 var uint32 ylo = FN_to_V(y);
45 if (xlo < ylo) { xhi += 1; }
46 return L2_to_I(xhi,xlo);
50 { // x ist Fixnum, y ist Bignum, also y länger
52 var sint64 x_ = FN_to_V(x); // Wert von x
54 var sintV x_ = FN_to_V(x); // Wert von x
56 if (FN_V_zerop(x,x_)) { return y; } // bei x=0 Ergebnis y
58 BN_to_NDS_1(y, MSDptr=,len=,LSDptr=); // NDS zu y bilden.
59 // len>=bn_minlength. len>pFN_maxlength erzwingen:
60 if ((bn_minlength==pFN_maxlength) && (len==pFN_maxlength))
61 { var sintD sign = sign_of_sintD(mspref(MSDptr,0));
62 lsprefnext(MSDptr) = sign; len++;
64 // x_ zu den oberen pFN_maxlength Digits von y addieren:
67 var uint64 y_ = lspref(LSDptr,0);
68 var uint64 y_new = y_+(uint64)x_;
69 lspref(LSDptr,0) = y_new;
71 var uintV y_ = pFN_maxlength_digits_at(LSDptr);
72 var uintV y_new = y_+(uintV)x_;
73 set_pFN_maxlength_digits_at(LSDptr,y_new);
75 var uintD* midptr = LSDptr lspop pFN_maxlength;
78 if (!FN_V_minusp(x,x_)) // kürzerer Summand war positiv
79 // Dann ist ein positiver Übertrag weiterzutragen
80 // (Beispiel: 0002FFFC + 0007 = 00030003)
81 { DS_1_plus(midptr,len-pFN_maxlength); }
85 if (FN_V_minusp(x,x_)) // kürzerer Summand war negativ
86 // Dann ist ein negativer Übertrag weiterzutragen
87 // (Beispiel: 00020003 + FFF5 = 0001FFF8)
88 { DS_minus1_plus(midptr,len-pFN_maxlength); }
90 return DS_to_I(MSDptr,len); // DS wieder zum Integer machen
96 { // x ist Bignum, y ist Fixnum, also x länger
98 var sint64 y_ = FN_to_V(y); // Wert von y
100 var sintV y_ = FN_to_V(y); // Wert von y
102 if (FN_V_zerop(y,y_)) { return x; } // bei y=0 Ergebnis x
104 BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); // NDS zu x bilden.
105 // len>=bn_minlength. len>pFN_maxlength erzwingen:
106 if ((bn_minlength==pFN_maxlength) && (len==pFN_maxlength))
107 { var sintD sign = sign_of_sintD(mspref(MSDptr,0));
108 lsprefnext(MSDptr) = sign; len++;
110 // y_ zu den oberen pFN_maxlength Digits von x addieren:
113 var uint64 x_ = lspref(LSDptr,0);
114 var uint64 x_new = x_+(uint64)y_;
115 lspref(LSDptr,0) = x_new;
117 var uintV x_ = pFN_maxlength_digits_at(LSDptr);
118 var uintV x_new = x_+(uintV)y_;
119 set_pFN_maxlength_digits_at(LSDptr,x_new);
121 var uintD* midptr = LSDptr lspop pFN_maxlength;
124 if (!FN_V_minusp(y,y_)) // kürzerer Summand war positiv
125 // Dann ist ein positiver Übertrag weiterzutragen
126 // (Beispiel: 0002FFFC + 0007 = 00030003)
127 { DS_1_plus(midptr,len-pFN_maxlength); }
131 if (FN_V_minusp(y,y_)) // kürzerer Summand war negativ
132 // Dann ist ein negativer Übertrag weiterzutragen
133 // (Beispiel: 00020003 + FFF5 = 0001FFF8)
134 { DS_minus1_plus(midptr,len-pFN_maxlength); }
136 return DS_to_I(MSDptr,len); // DS wieder zum Integer machen
139 { // x und y sind Bignums
141 if (TheBignum(x)->length > TheBignum(y)->length)
142 { // x das längere von beiden.
143 BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); // NDS zu x bilden.
144 var const uintD* yMSDptr;
146 var const uintD* yLSDptr;
147 BN_to_NDS_nocopy(y, yMSDptr=,ylen=,yLSDptr=); // NDS zu y bilden.
148 // yMSDptr/ylen/yLSDptr bilden die DS des kürzeren Arguments y.
151 { var uintD* midptr = LSDptr lspop ylen;
152 var uintD carry = addto_loop_lsp(yLSDptr,LSDptr,ylen);
155 if ((sintD)mspref(yMSDptr,0) >=0) // kürzerer Summand war positiv
156 // Dann ist ein positiver Übertrag weiterzutragen
157 // (Beispiel: 0002FFFC + 0007 = 00030003)
158 { DS_1_plus(midptr,len-ylen); }
162 if ((sintD)mspref(yMSDptr,0) <0) // kürzerer Summand war negativ
163 // Dann ist ein negativer Übertrag weiterzutragen
164 // (Beispiel: 00020003 + FFF5 = 0001FFF8)
165 { DS_minus1_plus(midptr,len-ylen); }
167 return DS_to_I(MSDptr,len); // DS wieder zum Integer machen
170 { // y das längere von beiden.
171 BN_to_NDS_1(y, MSDptr=,len=,LSDptr=); // NDS zu y bilden.
172 var const uintD* xMSDptr;
174 var const uintD* xLSDptr;
175 BN_to_NDS_nocopy(x, xMSDptr=,xlen=,xLSDptr=); // NDS zu x bilden.
176 // xMSDptr/xlen/xLSDptr bilden die DS des kürzeren Arguments x.
177 // len>xlen erzwingen:
179 { var sintD sign = sign_of_sintD(mspref(MSDptr,0));
180 lsprefnext(MSDptr) = sign; len++;
183 { var uintD* midptr = LSDptr lspop xlen;
184 var uintD carry = addto_loop_lsp(xLSDptr,LSDptr,xlen);
187 if ((sintD)mspref(xMSDptr,0) >=0) // kürzerer Summand war positiv
188 // Dann ist ein positiver Übertrag weiterzutragen
189 // (Beispiel: 0002FFFC + 0007 = 00030003)
190 { DS_1_plus(midptr,len-xlen); }
194 if ((sintD)mspref(xMSDptr,0) <0) // kürzerer Summand war negativ
195 // Dann ist ein negativer Übertrag weiterzutragen
196 // (Beispiel: 00020003 + FFF5 = 0001FFF8)
197 { DS_minus1_plus(midptr,len-xlen); }
199 return DS_to_I(MSDptr,len); // DS wieder zum Integer machen