1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Implement scm_lognot with new integer library

* libguile/integers.c (scm_integer_lognot_i, scm_integer_lognot_z):
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_lognot): Use new internal functions.
This commit is contained in:
Andy Wingo 2021-12-19 14:43:05 +01:00
parent 89cd48fcac
commit b41714d277
3 changed files with 25 additions and 15 deletions

View file

@ -2028,3 +2028,20 @@ scm_integer_logbit_uz (unsigned long index, SCM n)
scm_remember_upto_here_1 (n);
return val;
}
SCM
scm_integer_lognot_i (scm_t_inum n)
{
return SCM_I_MAKINUM (~n);
}
SCM
scm_integer_lognot_z (SCM n)
{
mpz_t result, zn;
mpz_init (result);
alias_bignum_to_mpz (scm_bignum (n), zn);
mpz_com (result, zn);
scm_remember_upto_here_1 (n);
return take_mpz (result);
}

View file

@ -151,6 +151,9 @@ SCM_INTERNAL int scm_integer_logtest_zz (SCM x, SCM y);
SCM_INTERNAL int scm_integer_logbit_ui (unsigned long bit, scm_t_inum n);
SCM_INTERNAL int scm_integer_logbit_uz (unsigned long bit, SCM n);
SCM_INTERNAL SCM scm_integer_lognot_i (scm_t_inum n);
SCM_INTERNAL SCM scm_integer_lognot_z (SCM n);
#endif /* SCM_INTEGERS_H */

View file

@ -3177,22 +3177,12 @@ SCM_DEFINE (scm_lognot, "lognot", 1, 0, 0,
"@end lisp")
#define FUNC_NAME s_scm_lognot
{
if (SCM_I_INUMP (n)) {
/* No overflow here, just need to toggle all the bits making up the inum.
Enhancement: No need to strip the tag and add it back, could just xor
a block of 1 bits, if that worked with the various debug versions of
the SCM typedef. */
return SCM_I_MAKINUM (~ SCM_I_INUM (n));
} else if (SCM_BIGP (n)) {
SCM result = scm_i_mkbig ();
mpz_com (SCM_I_BIG_MPZ (result), SCM_I_BIG_MPZ (n));
scm_remember_upto_here_1 (n);
return result;
} else {
if (SCM_I_INUMP (n))
return scm_integer_lognot_i (SCM_I_INUM (n));
else if (SCM_BIGP (n))
return scm_integer_lognot_z (n);
else
SCM_WRONG_TYPE_ARG (SCM_ARG1, n);
}
}
#undef FUNC_NAME