1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-23 12:00:21 +02:00

divide2double refactor

* libguile/integers.c (scm_integer_set_mpz_z): New internal function.
(scm_integer_init_set_mpz_z): Rename from scm_integer_to_mpz_z.
* libguile/integers.h:
* libguile/numbers.c (scm_i_divide2double): Avoid SCM_I_BIG_MPZ.
This commit is contained in:
Andy Wingo 2022-01-07 10:48:31 +01:00
parent c06fc3df54
commit 0754dbf3e8
3 changed files with 19 additions and 12 deletions

View file

@ -3037,14 +3037,21 @@ scm_integer_to_uint64_z (struct scm_bignum *z, uint64_t *val)
} }
void void
scm_integer_to_mpz_z (struct scm_bignum *z, mpz_t n) scm_integer_set_mpz_z (struct scm_bignum *z, mpz_t n)
{ {
mpz_t zn; mpz_t zn;
alias_bignum_to_mpz (z, zn); alias_bignum_to_mpz (z, zn);
mpz_init_set (n, zn); mpz_set (n, zn);
scm_remember_upto_here_1 (z); scm_remember_upto_here_1 (z);
} }
void
scm_integer_init_set_mpz_z (struct scm_bignum *z, mpz_t n)
{
mpz_init (n);
scm_integer_set_mpz_z (z, n);
}
void void
scm_integer_exact_sqrt_i (scm_t_inum k, SCM *s, SCM *r) scm_integer_exact_sqrt_i (scm_t_inum k, SCM *s, SCM *r)
{ {

View file

@ -33,7 +33,8 @@ scm_bignum (SCM x)
} }
SCM_INTERNAL SCM scm_integer_from_mpz (const mpz_t n); SCM_INTERNAL SCM scm_integer_from_mpz (const mpz_t n);
SCM_INTERNAL void scm_integer_to_mpz_z (struct scm_bignum *z, mpz_t n); SCM_INTERNAL void scm_integer_set_mpz_z (struct scm_bignum *z, mpz_t n);
SCM_INTERNAL void scm_integer_init_set_mpz_z (struct scm_bignum *z, mpz_t n);
SCM_INTERNAL int scm_is_integer_odd_i (scm_t_inum i); SCM_INTERNAL int scm_is_integer_odd_i (scm_t_inum i);
SCM_INTERNAL int scm_is_integer_odd_z (struct scm_bignum *z); SCM_INTERNAL int scm_is_integer_odd_z (struct scm_bignum *z);

View file

@ -443,18 +443,17 @@ scm_i_divide2double (SCM n, SCM d)
mpz_t nn, dd, lo, hi, x; mpz_t nn, dd, lo, hi, x;
ssize_t e; ssize_t e;
if (SCM_LIKELY (SCM_I_INUMP (d))) if (SCM_I_INUMP (d))
{ {
if (SCM_LIKELY if (SCM_I_INUMP (n)
(SCM_I_INUMP (n)
&& INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE (SCM_I_INUM (n)) && INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE (SCM_I_INUM (n))
&& INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE (SCM_I_INUM (d)))) && INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE (SCM_I_INUM (d)))
/* If both N and D can be losslessly converted to doubles, then /* If both N and D can be losslessly converted to doubles, then
we can rely on IEEE floating point to do proper rounding much we can rely on IEEE floating point to do proper rounding much
faster than we can. */ faster than we can. */
return ((double) SCM_I_INUM (n)) / ((double) SCM_I_INUM (d)); return ((double) SCM_I_INUM (n)) / ((double) SCM_I_INUM (d));
if (SCM_UNLIKELY (scm_is_eq (d, SCM_INUM0))) if (scm_is_eq (d, SCM_INUM0))
{ {
if (scm_is_true (scm_positive_p (n))) if (scm_is_true (scm_positive_p (n)))
return 1.0 / 0.0; return 1.0 / 0.0;
@ -467,12 +466,12 @@ scm_i_divide2double (SCM n, SCM d)
mpz_init_set_si (dd, SCM_I_INUM (d)); mpz_init_set_si (dd, SCM_I_INUM (d));
} }
else else
mpz_init_set (dd, SCM_I_BIG_MPZ (d)); scm_integer_init_set_mpz_z (scm_bignum (d), dd);
if (SCM_I_INUMP (n)) if (SCM_I_INUMP (n))
mpz_init_set_si (nn, SCM_I_INUM (n)); mpz_init_set_si (nn, SCM_I_INUM (n));
else else
mpz_init_set (nn, SCM_I_BIG_MPZ (n)); scm_integer_init_set_mpz_z (scm_bignum (n), nn);
neg = (mpz_sgn (nn) < 0) ^ (mpz_sgn (dd) < 0); neg = (mpz_sgn (nn) < 0) ^ (mpz_sgn (dd) < 0);
mpz_abs (nn, nn); mpz_abs (nn, nn);
@ -7044,7 +7043,7 @@ scm_to_mpz (SCM val, mpz_t rop)
if (SCM_I_INUMP (val)) if (SCM_I_INUMP (val))
mpz_set_si (rop, SCM_I_INUM (val)); mpz_set_si (rop, SCM_I_INUM (val));
else if (SCM_BIGP (val)) else if (SCM_BIGP (val))
scm_integer_to_mpz_z (scm_bignum (val), rop); scm_integer_set_mpz_z (scm_bignum (val), rop);
else else
scm_wrong_type_arg_msg (NULL, 0, val, "exact integer"); scm_wrong_type_arg_msg (NULL, 0, val, "exact integer");
} }