@@ -51,6 +51,9 @@ STATIC int mpn_cmp(const mpz_dig_t *idig, uint ilen, const mpz_dig_t *jdig, uint
5151STATIC uint mpn_shl (mpz_dig_t * idig , mpz_dig_t * jdig , uint jlen , uint n ) {
5252 uint n_whole = (n + DIG_SIZE - 1 ) / DIG_SIZE ;
5353 uint n_part = n % DIG_SIZE ;
54+ if (n_part == 0 ) {
55+ n_part = DIG_SIZE ;
56+ }
5457
5558 // start from the high end of the digit arrays
5659 idig += jlen + n_whole - 1 ;
@@ -67,7 +70,7 @@ STATIC uint mpn_shl(mpz_dig_t *idig, mpz_dig_t *jdig, uint jlen, uint n) {
6770 // store remaining bits
6871 * idig = d >> (DIG_SIZE - n_part );
6972 idig -= n_whole - 1 ;
70- memset (idig , 0 , n_whole - 1 );
73+ memset (idig , 0 , ( n_whole - 1 ) * sizeof ( mpz_dig_t ) );
7174
7275 // work out length of result
7376 jlen += n_whole ;
@@ -412,6 +415,12 @@ mpz_t *mpz_from_int(machine_int_t val) {
412415 return z ;
413416}
414417
418+ mpz_t * mpz_from_ll (long long val ) {
419+ mpz_t * z = mpz_zero ();
420+ mpz_set_from_ll (z , val );
421+ return z ;
422+ }
423+
415424mpz_t * mpz_from_str (const char * str , uint len , bool neg , uint base ) {
416425 mpz_t * z = mpz_zero ();
417426 mpz_set_from_str (z , str , len , neg , base );
@@ -469,17 +478,38 @@ void mpz_set(mpz_t *dest, const mpz_t *src) {
469478void mpz_set_from_int (mpz_t * z , machine_int_t val ) {
470479 mpz_need_dig (z , MPZ_NUM_DIG_FOR_INT );
471480
481+ machine_uint_t uval ;
472482 if (val < 0 ) {
473483 z -> neg = 1 ;
474- val = - val ;
484+ uval = - val ;
485+ } else {
486+ z -> neg = 0 ;
487+ uval = val ;
488+ }
489+
490+ z -> len = 0 ;
491+ while (uval > 0 ) {
492+ z -> dig [z -> len ++ ] = uval & DIG_MASK ;
493+ uval >>= DIG_SIZE ;
494+ }
495+ }
496+
497+ void mpz_set_from_ll (mpz_t * z , long long val ) {
498+ mpz_need_dig (z , MPZ_NUM_DIG_FOR_LL );
499+
500+ unsigned long long uval ;
501+ if (val < 0 ) {
502+ z -> neg = 1 ;
503+ uval = - val ;
475504 } else {
476505 z -> neg = 0 ;
506+ uval = val ;
477507 }
478508
479509 z -> len = 0 ;
480- while (val > 0 ) {
481- z -> dig [z -> len ++ ] = val & DIG_MASK ;
482- val >>= DIG_SIZE ;
510+ while (uval > 0 ) {
511+ z -> dig [z -> len ++ ] = uval & DIG_MASK ;
512+ uval >>= DIG_SIZE ;
483513 }
484514}
485515
0 commit comments