mpfr_prec_t mpfr_min_prec (mpfr_srcptr x) { if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) return 0; /* from a suggestion by Andreas Enge (2010-11-18) */ return MPFR_LIMB_SIZE (x) * GMP_NUMB_BITS - mpn_scan1 (MPFR_MANT (x), 0); }
void check (void) { unsigned long i, got, want; x[SIZE] = 1; for (i = 0; i < SIZE*GMP_NUMB_BITS; i++) { got = refmpn_scan1 (x, i); want = mpn_scan1 (x, i); if (got != want) { printf ("mpn_scan1\n"); printf (" i %lu\n", i); printf (" got %lu\n", got); printf (" want %lu\n", want); mpn_trace (" x ", x, SIZE); abort (); } } x[SIZE] = 0; for (i = 0; i < SIZE*GMP_NUMB_BITS; i++) { got = refmpn_scan0 (x, i); want = mpn_scan0 (x, i); if (got != want) { printf ("mpn_scan0\n"); printf (" i %lu\n", i); printf (" got %lu\n", got); printf (" want %lu\n", want); mpn_trace (" x ", x, SIZE); abort (); } } }
unsigned long __fmpz_power_of_two(const fmpz_t x) { if (x[0] == 0) return -1L; return mpn_scan1(x + 1, 0); }
void _gst_mpz_gcd (gst_mpz *g, const gst_mpz *u, const gst_mpz *v) { int g_zero_bits, u_zero_bits, v_zero_bits; mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs; mp_ptr tp; mp_ptr up = u->d; mp_size_t usize = ABS (u->size); mp_ptr vp = v->d; mp_size_t vsize = ABS (v->size); mp_size_t gsize; /* GCD(0, V) == GCD (U, 1) == V. */ if (usize == 0 || (vsize == 1 && vp[0] == 1)) { gst_mpz_copy_abs (g, v); return; } /* GCD(U, 0) == GCD (1, V) == U. */ if (vsize == 0 || (usize == 1 && up[0] == 1)) { gst_mpz_copy_abs (g, u); return; } if (usize == 1) { gst_mpz_realloc (g, 1); g->size = 1; g->d[0] = mpn_gcd_1 (vp, vsize, up[0]); return; } if (vsize == 1) { gst_mpz_realloc (g, 1); g->size = 1; g->d[0] = mpn_gcd_1 (up, usize, vp[0]); return; } /* Eliminate low zero bits from U and V and move to temporary storage. */ u_zero_bits = mpn_scan1 (up, 0); u_zero_limbs = u_zero_bits / BITS_PER_MP_LIMB; u_zero_bits &= BITS_PER_MP_LIMB - 1; up += u_zero_limbs; usize -= u_zero_limbs; /* Operands could be destroyed for big-endian case, but let's be tidy. */ tp = up; up = (mp_ptr) alloca (usize * SIZEOF_MP_LIMB_T); if (u_zero_bits != 0) { mpn_rshift (up, tp, usize, u_zero_bits); usize -= up[usize - 1] == 0; } else MPN_COPY (up, tp, usize); v_zero_bits = mpn_scan1 (vp, 0); v_zero_limbs = v_zero_bits / BITS_PER_MP_LIMB; v_zero_bits &= BITS_PER_MP_LIMB - 1; vp += v_zero_limbs; vsize -= v_zero_limbs; /* Operands could be destroyed for big-endian case, but let's be tidy. */ tp = vp; vp = (mp_ptr) alloca (vsize * SIZEOF_MP_LIMB_T); if (v_zero_bits != 0) { mpn_rshift (vp, tp, vsize, v_zero_bits); vsize -= vp[vsize - 1] == 0; } else MPN_COPY (vp, tp, vsize); if (u_zero_limbs > v_zero_limbs) { g_zero_limbs = v_zero_limbs; g_zero_bits = v_zero_bits; } else if (u_zero_limbs < v_zero_limbs) { g_zero_limbs = u_zero_limbs; g_zero_bits = u_zero_bits; } else /* Equal. */ { g_zero_limbs = u_zero_limbs; g_zero_bits = MIN (u_zero_bits, v_zero_bits); } /* Call mpn_gcd. The 2nd argument must not have more bits than the 1st. */ vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1])) ? mpn_gcd (vp, vp, vsize, up, usize) : mpn_gcd (vp, up, usize, vp, vsize); /* Here G <-- V << (g_zero_limbs*BITS_PER_MP_LIMB + g_zero_bits). */ gsize = vsize + g_zero_limbs; if (g_zero_bits != 0) { mp_limb_t cy_limb; gsize += (vp[vsize - 1] >> (BITS_PER_MP_LIMB - g_zero_bits)) != 0; if (g->alloc < gsize) gst_mpz_realloc (g, gsize); MPN_ZERO (g->d, g_zero_limbs); tp = g->d + g_zero_limbs; cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits); if (cy_limb != 0) tp[vsize] = cy_limb; }