wingo pushed a commit to branch wip-inline-digits
in repository guile.
commit 774b863bfcfba724e4caf7dc4b580260acf55138
Author: Andy Wingo <[email protected]>
AuthorDate: Sun Jan 9 20:48:45 2022 +0100
Less pessimal scm_integer_sub_zi
* libguile/integers.c (scm_integer_sub_zi): Only delegate to
scm_integer_add_ii if y is negative.
---
libguile/integers.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/libguile/integers.c b/libguile/integers.c
index 60c0fd34a..b368f52db 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -2875,10 +2875,22 @@ scm_integer_sub_iz (scm_t_inum x, struct scm_bignum *y)
SCM
scm_integer_sub_zi (struct scm_bignum *x, scm_t_inum y)
{
- // Assumes that -INUM_MIN can fit in a scm_t_inum, even if that
- // scm_t_inum is not fixable, and that scm_integer_add_ii can handle
- // scm_t_inum inputs outside the fixable range.
- return scm_integer_add_zi (x, -y);
+ if (y == 0)
+ return scm_from_bignum (x);
+ if (y < 0)
+ // Assumes that -INUM_MIN can fit in a scm_t_inum, even if that
+ // scm_t_inum is not fixable, and that scm_integer_add_ii can handle
+ // scm_t_inum inputs outside the fixable range.
+ return scm_integer_add_zi (x, -y);
+
+ mpz_t result, zx;
+ mpz_init (result);
+ alias_bignum_to_mpz (x, zx);
+ mpz_sub_ui (result, zx, y);
+ scm_remember_upto_here_1 (x);
+ // FIXME: We know that if X is negative, no need to check if
+ // result is fixable.
+ return take_mpz (result);
}
SCM