summaryrefslogtreecommitdiff
path: root/libguile/numbers.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-10-03 21:35:21 +0200
committerAndy Wingo <wingo@pobox.com>2013-10-03 21:35:21 +0200
commitd7928d7c61f297dca574e20bb5815253e90b3a36 (patch)
treef8b4ac0103eaded5c3b61573212ab0dc5fd5fcd1 /libguile/numbers.c
parentae07b8e70bfc53220d7017bb7edcdb6c329d5bd5 (diff)
parentd7794a9d07ba657a29f7e608c3e558c437806def (diff)
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts: libguile/deprecated.h libguile/programs.c libguile/programs.h
Diffstat (limited to 'libguile/numbers.c')
-rw-r--r--libguile/numbers.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 7ccbeecf3..b91f4c308 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -4977,11 +4977,14 @@ left_shift_exact_integer (SCM n, long count)
{
scm_t_inum nn = SCM_I_INUM (n);
- /* Left shift of count >= SCM_I_FIXNUM_BIT-1 will always
+ /* Left shift of count >= SCM_I_FIXNUM_BIT-1 will almost[*] always
overflow a non-zero fixnum. For smaller shifts we check the
bits going into positions above SCM_I_FIXNUM_BIT-1. If they're
all 0s for nn>=0, or all 1s for nn<0 then there's no overflow.
- Those bits are "nn >> (SCM_I_FIXNUM_BIT-1 - count)". */
+ Those bits are "nn >> (SCM_I_FIXNUM_BIT-1 - count)".
+
+ [*] There's one exception:
+ (-1) << SCM_I_FIXNUM_BIT-1 == SCM_MOST_NEGATIVE_FIXNUM */
if (nn == 0)
return n;
@@ -4994,8 +4997,8 @@ left_shift_exact_integer (SCM n, long count)
SCM result = scm_i_inum2big (nn);
mpz_mul_2exp (SCM_I_BIG_MPZ (result), SCM_I_BIG_MPZ (result),
count);
- return result;
- }
+ return scm_i_normbig (result);
+ }
}
else if (SCM_BIGP (n))
{