@@ -173,6 +173,69 @@ STATIC uint mpn_sub(mpz_dig_t *idig, const mpz_dig_t *jdig, uint jlen, const mpz
173173 return idig + 1 - oidig ;
174174}
175175
176+ /* computes i = j & k
177+ returns number of digits in i
178+ assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
179+ can have i, j, k pointing to same memory
180+ */
181+ STATIC uint mpn_and (mpz_dig_t * idig , const mpz_dig_t * jdig , uint jlen , const mpz_dig_t * kdig , uint klen ) {
182+ mpz_dig_t * oidig = idig ;
183+
184+ jlen -= klen ;
185+
186+ for (; klen > 0 ; -- klen , ++ idig , ++ jdig , ++ kdig ) {
187+ * idig = * jdig & * kdig ;
188+ }
189+
190+ for (; jlen > 0 ; -- jlen , ++ idig ) {
191+ * idig = 0 ;
192+ }
193+
194+ return idig - oidig ;
195+ }
196+
197+ /* computes i = j | k
198+ returns number of digits in i
199+ assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
200+ can have i, j, k pointing to same memory
201+ */
202+ STATIC uint mpn_or (mpz_dig_t * idig , const mpz_dig_t * jdig , uint jlen , const mpz_dig_t * kdig , uint klen ) {
203+ mpz_dig_t * oidig = idig ;
204+
205+ jlen -= klen ;
206+
207+ for (; klen > 0 ; -- klen , ++ idig , ++ jdig , ++ kdig ) {
208+ * idig = * jdig | * kdig ;
209+ }
210+
211+ for (; jlen > 0 ; -- jlen , ++ idig , ++ jdig ) {
212+ * idig = * jdig ;
213+ }
214+
215+ return idig - oidig ;
216+ }
217+
218+ /* computes i = j ^ k
219+ returns number of digits in i
220+ assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
221+ can have i, j, k pointing to same memory
222+ */
223+ STATIC uint mpn_xor (mpz_dig_t * idig , const mpz_dig_t * jdig , uint jlen , const mpz_dig_t * kdig , uint klen ) {
224+ mpz_dig_t * oidig = idig ;
225+
226+ jlen -= klen ;
227+
228+ for (; klen > 0 ; -- klen , ++ idig , ++ jdig , ++ kdig ) {
229+ * idig = * jdig ^ * kdig ;
230+ }
231+
232+ for (; jlen > 0 ; -- jlen , ++ idig , ++ jdig ) {
233+ * idig = * jdig ;
234+ }
235+
236+ return idig - oidig ;
237+ }
238+
176239/* computes i = i * d1 + d2
177240 returns number of digits in i
178241 assumes enough memory in i; assumes normalised i; assumes dmul != 0
@@ -805,6 +868,75 @@ void mpz_sub_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
805868 }
806869}
807870
871+ /* computes dest = lhs & rhs
872+ can have dest, lhs, rhs the same
873+ */
874+ void mpz_and_inpl (mpz_t * dest , const mpz_t * lhs , const mpz_t * rhs ) {
875+ if (mpn_cmp (lhs -> dig , lhs -> len , rhs -> dig , rhs -> len ) < 0 ) {
876+ const mpz_t * temp = lhs ;
877+ lhs = rhs ;
878+ rhs = temp ;
879+ }
880+
881+ if (lhs -> neg == rhs -> neg ) {
882+ mpz_need_dig (dest , lhs -> len );
883+ dest -> len = mpn_and (dest -> dig , lhs -> dig , lhs -> len , rhs -> dig , rhs -> len );
884+ } else {
885+ mpz_need_dig (dest , lhs -> len );
886+ // TODO
887+ assert (0 );
888+ // dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
889+ }
890+
891+ dest -> neg = lhs -> neg ;
892+ }
893+
894+ /* computes dest = lhs | rhs
895+ can have dest, lhs, rhs the same
896+ */
897+ void mpz_or_inpl (mpz_t * dest , const mpz_t * lhs , const mpz_t * rhs ) {
898+ if (mpn_cmp (lhs -> dig , lhs -> len , rhs -> dig , rhs -> len ) < 0 ) {
899+ const mpz_t * temp = lhs ;
900+ lhs = rhs ;
901+ rhs = temp ;
902+ }
903+
904+ if (lhs -> neg == rhs -> neg ) {
905+ mpz_need_dig (dest , lhs -> len );
906+ dest -> len = mpn_or (dest -> dig , lhs -> dig , lhs -> len , rhs -> dig , rhs -> len );
907+ } else {
908+ mpz_need_dig (dest , lhs -> len );
909+ // TODO
910+ assert (0 );
911+ // dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
912+ }
913+
914+ dest -> neg = lhs -> neg ;
915+ }
916+
917+ /* computes dest = lhs ^ rhs
918+ can have dest, lhs, rhs the same
919+ */
920+ void mpz_xor_inpl (mpz_t * dest , const mpz_t * lhs , const mpz_t * rhs ) {
921+ if (mpn_cmp (lhs -> dig , lhs -> len , rhs -> dig , rhs -> len ) < 0 ) {
922+ const mpz_t * temp = lhs ;
923+ lhs = rhs ;
924+ rhs = temp ;
925+ }
926+
927+ if (lhs -> neg == rhs -> neg ) {
928+ mpz_need_dig (dest , lhs -> len );
929+ dest -> len = mpn_xor (dest -> dig , lhs -> dig , lhs -> len , rhs -> dig , rhs -> len );
930+ } else {
931+ mpz_need_dig (dest , lhs -> len );
932+ // TODO
933+ assert (0 );
934+ // dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
935+ }
936+
937+ dest -> neg = 0 ;
938+ }
939+
808940/* computes dest = lhs * rhs
809941 can have dest, lhs, rhs the same
810942*/
0 commit comments