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

(scm_i_divide): For big/big wanting inexact, use mpq_get_d

rather than converting to doubles, to avoid inf or nan when the inputs
are too big for a double but the quotient does fit.  This affects
conversions exact->inexact of big fractions.
This commit is contained in:
Kevin Ryde 2006-05-09 00:25:11 +00:00
parent 101bd61cf5
commit 65581bc84d

View file

@ -4779,28 +4779,33 @@ scm_i_divide (SCM x, SCM y, int inexact)
else else
{ {
/* big_x / big_y */ /* big_x / big_y */
int divisible_p = mpz_divisible_p (SCM_I_BIG_MPZ (x), if (inexact)
SCM_I_BIG_MPZ (y)); {
if (divisible_p) /* It's easily possible for the ratio x/y to fit a double
{ but one or both x and y be too big to fit a double,
SCM result = scm_i_mkbig (); hence the use of mpq_get_d rather than converting and
mpz_divexact (SCM_I_BIG_MPZ (result), dividing. */
SCM_I_BIG_MPZ (x), mpq_t q;
SCM_I_BIG_MPZ (y)); *mpq_numref(q) = *SCM_I_BIG_MPZ (x);
scm_remember_upto_here_2 (x, y); *mpq_denref(q) = *SCM_I_BIG_MPZ (y);
return scm_i_normbig (result); return scm_from_double (mpq_get_d (q));
} }
else else
{ {
if (inexact) int divisible_p = mpz_divisible_p (SCM_I_BIG_MPZ (x),
{ SCM_I_BIG_MPZ (y));
double dbx = mpz_get_d (SCM_I_BIG_MPZ (x)); if (divisible_p)
double dby = mpz_get_d (SCM_I_BIG_MPZ (y)); {
scm_remember_upto_here_2 (x, y); SCM result = scm_i_mkbig ();
return scm_from_double (dbx / dby); mpz_divexact (SCM_I_BIG_MPZ (result),
} SCM_I_BIG_MPZ (x),
else return scm_i_make_ratio (x, y); SCM_I_BIG_MPZ (y));
} scm_remember_upto_here_2 (x, y);
return scm_i_normbig (result);
}
else
return scm_i_make_ratio (x, y);
}
} }
} }
else if (SCM_REALP (y)) else if (SCM_REALP (y))