void mpf_set_d (mpf_ptr r, double d) { int negative; DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), __gmp_invalid_operation ()); if (UNLIKELY (d == 0)) { SIZ(r) = 0; EXP(r) = 0; return; } negative = d < 0; d = ABS (d); SIZ(r) = negative ? -LIMBS_PER_DOUBLE : LIMBS_PER_DOUBLE; EXP(r) = __gmp_extract_double (PTR(r), d); }
choke me #endif void mpq_set_d (mpq_ptr dest, double d) { int negative; mp_exp_t exp; mp_limb_t tp[LIMBS_PER_DOUBLE]; mp_ptr np, dp; mp_size_t nn, dn; int c; negative = d < 0; d = ABS (d); exp = __gmp_extract_double (tp, d); /* There are two main version of the conversion. The `then' arm handles things that have a fractional part, while the `else' part handles only integers. */ #if BITS_PER_MP_LIMB == 32 if (exp <= 1 || (exp == 2 && tp[0] != 0)) #else if (exp <= 1) #endif { if (d == 0.0) { SIZ(&(dest->_mp_num)) = 0; SIZ(&(dest->_mp_den)) = 1; PTR(&(dest->_mp_den))[0] = 1; return; } dn = -exp; if (dest->_mp_num._mp_alloc < 3) _mpz_realloc (&(dest->_mp_num), 3); np = PTR(&(dest->_mp_num)); #if BITS_PER_MP_LIMB == 32 if ((tp[0] | tp[1]) == 0) np[0] = tp[2], nn = 1; else if (tp[0] == 0) np[1] = tp[2], np[0] = tp[1], nn = 2; else np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 3; #else if (tp[0] == 0) np[0] = tp[1], nn = 1; else np[1] = tp[1], np[0] = tp[0], nn = 2; #endif dn += nn + 1; if (dest->_mp_den._mp_alloc < dn) _mpz_realloc (&(dest->_mp_den), dn); dp = PTR(&(dest->_mp_den)); MPN_ZERO (dp, dn - 1); dp[dn - 1] = 1; count_trailing_zeros (c, np[0] | dp[0]); if (c != 0) { mpn_rshift (np, np, nn, c); nn -= np[nn - 1] == 0; mpn_rshift (dp, dp, dn, c); dn -= dp[dn - 1] == 0; } SIZ(&(dest->_mp_den)) = dn; SIZ(&(dest->_mp_num)) = negative ? -nn : nn; } else { nn = exp; if (dest->_mp_num._mp_alloc < nn) _mpz_realloc (&(dest->_mp_num), nn); np = PTR(&(dest->_mp_num)); #if BITS_PER_MP_LIMB == 32 switch (nn) { default: MPN_ZERO (np, nn - 3); np += nn - 3; /* fall through */ case 3: np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 2: np[1] = tp[2], np[0] = tp[1]; break; } #else switch (nn) { default: MPN_ZERO (np, nn - 2); np += nn - 2; /* fall through */ case 2: np[1] = tp[1], np[0] = tp[0]; break; } #endif dp = PTR(&(dest->_mp_den)); dp[0] = 1; SIZ(&(dest->_mp_den)) = 1; SIZ(&(dest->_mp_num)) = negative ? -nn : nn; } }
int mpz_cmpabs_d (mpz_srcptr z, double d) { mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb; mp_srcptr zp; mp_size_t zsize; int dexp; /* 1. Check for either operand zero. */ zsize = SIZ(z); if (d == 0.0) return (zsize != 0); if (zsize == 0) return (d != 0 ? -1 : 0); /* 2. Ignore signs. */ zsize = ABS(zsize); d = ABS(d); /* 3. Small d, knowing abs(z) >= 1. */ if (d < 1.0) return 1; dexp = __gmp_extract_double (darray, d); ASSERT (dexp >= 1); /* 4. Check for different high limb positions. */ if (zsize != dexp) return (zsize >= dexp ? 1 : -1); /* 5. Limb data. */ zp = PTR(z); #if LIMBS_PER_DOUBLE == 2 RETURN_CMP (zp[zsize-1], darray[1]); if (zsize == 1) return (darray[0] != 0 ? -1 : 0); RETURN_CMP (zp[zsize-2], darray[0]); RETURN_NONZERO (zp, zsize-2, 1); #else #if LIMBS_PER_DOUBLE == 3 RETURN_CMP (zp[zsize-1], darray[2]); if (zsize == 1) return ((darray[0] | darray[1]) != 0 ? -1 : 0); RETURN_CMP (zp[zsize-2], darray[1]); if (zsize == 2) return (darray[0] != 0 ? -1 : 0); RETURN_CMP (zp[zsize-3], darray[0]); RETURN_NONZERO (zp, zsize-3, 1); #else for (i = 1; i <= LIMBS_PER_DOUBLE; i++) { RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]); if (i >= zsize) RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -1); } RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, 1); #endif #endif }
int mpz_cmp_d (mpz_srcptr z, double d) { mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb; mp_srcptr zp; mp_size_t zsize; int dexp, ret; /* 1. Either operand zero. */ zsize = SIZ(z); if (d == 0.0) return zsize; if (zsize == 0) return (d < 0.0 ? 1 : -1); /* 2. Opposite signs. */ if (zsize >= 0) { if (d < 0.0) return 1; /* >=0 cmp <0 */ ret = 1; } else { if (d >= 0.0) return -1; /* <0 cmp >=0 */ ret = -1; d = -d; zsize = -zsize; } /* 3. Small d, knowing abs(z) >= 1. */ if (d < 1.0) return ret; dexp = __gmp_extract_double (darray, d); ASSERT (dexp >= 1); /* 4. Different high limb positions. */ if (zsize != dexp) return (zsize >= dexp ? ret : -ret); /* 5. Limb data. */ zp = PTR(z); #if LIMBS_PER_DOUBLE == 2 RETURN_CMP (zp[zsize-1], darray[1]); if (zsize == 1) return (darray[0] != 0 ? -ret : 0); RETURN_CMP (zp[zsize-2], darray[0]); RETURN_NONZERO (zp, zsize-2, ret); #else #if LIMBS_PER_DOUBLE == 3 RETURN_CMP (zp[zsize-1], darray[2]); if (zsize == 1) return ((darray[0] | darray[1]) != 0 ? -ret : 0); RETURN_CMP (zp[zsize-2], darray[1]); if (zsize == 2) return (darray[0] != 0 ? -ret : 0); RETURN_CMP (zp[zsize-3], darray[0]); RETURN_NONZERO (zp, zsize-3, ret); #else for (i = 1; i <= LIMBS_PER_DOUBLE; i++) { RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]); if (i >= zsize) RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -ret); } RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, ret); #endif #endif }
choke me #endif void mpq_set_d (mpq_ptr dest, double d) { int negative; mp_exp_t exp; mp_limb_t tp[LIMBS_PER_DOUBLE]; mp_ptr np, dp; mp_size_t nn, dn; int c; DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), __gmp_invalid_operation ()); negative = d < 0; d = ABS (d); exp = __gmp_extract_double (tp, d); /* There are two main version of the conversion. The `then' arm handles numbers with a fractional part, while the `else' arm handles integers. */ #if LIMBS_PER_DOUBLE == 4 if (exp <= 1 || (exp == 2 && (tp[0] | tp[1]) != 0)) #endif #if LIMBS_PER_DOUBLE == 3 if (exp <= 1 || (exp == 2 && tp[0] != 0)) #endif #if LIMBS_PER_DOUBLE == 2 if (exp <= 1) #endif { if (d == 0.0) { SIZ(NUM(dest)) = 0; SIZ(DEN(dest)) = 1; PTR(DEN(dest))[0] = 1; return; } #if LIMBS_PER_DOUBLE == 4 np = MPZ_NEWALLOC (NUM(dest), 4); if ((tp[0] | tp[1] | tp[2]) == 0) np[0] = tp[3], nn = 1; else if ((tp[0] | tp[1]) == 0) np[1] = tp[3], np[0] = tp[2], nn = 2; else if (tp[0] == 0) np[2] = tp[3], np[1] = tp[2], np[0] = tp[1], nn = 3; else np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 4; #endif #if LIMBS_PER_DOUBLE == 3 np = MPZ_NEWALLOC (NUM(dest), 3); if ((tp[0] | tp[1]) == 0) np[0] = tp[2], nn = 1; else if (tp[0] == 0) np[1] = tp[2], np[0] = tp[1], nn = 2; else np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 3; #endif #if LIMBS_PER_DOUBLE == 2 np = MPZ_NEWALLOC (NUM(dest), 2); if (tp[0] == 0) np[0] = tp[1], nn = 1; else np[1] = tp[1], np[0] = tp[0], nn = 2; #endif dn = nn + 1 - exp; ASSERT (dn > 0); /* -exp >= -1; nn >= 1*/ dp = MPZ_NEWALLOC (DEN(dest), dn); MPN_ZERO (dp, dn - 1); dp[dn - 1] = 1; count_trailing_zeros (c, np[0] | dp[0]); if (c != 0) { mpn_rshift (np, np, nn, c); nn -= np[nn - 1] == 0; --dn; dp[dn - 1] = CNST_LIMB(1) << (GMP_LIMB_BITS - c); } SIZ(DEN(dest)) = dn; } else { nn = exp; np = MPZ_NEWALLOC (NUM(dest), nn); switch (nn) { default: MPN_ZERO (np, nn - LIMBS_PER_DOUBLE); np += nn - LIMBS_PER_DOUBLE; /* fall through */ #if LIMBS_PER_DOUBLE == 2 case 2: np[1] = tp[1], np[0] = tp[0]; break; #endif #if LIMBS_PER_DOUBLE == 3 case 3: np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 2: np[1] = tp[2], np[0] = tp[1]; break; #endif #if LIMBS_PER_DOUBLE == 4 case 4: np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0]; break; case 3: np[2] = tp[3], np[1] = tp[2], np[0] = tp[1]; break; case 2: np[1] = tp[3], np[0] = tp[2]; break; #endif } *PTR(DEN(dest)) = 1; SIZ(DEN(dest)) = 1; } SIZ(NUM(dest)) = negative ? -nn : nn; }