From 7f48b4d3702bbd0b3f554e48065a5ddae82d070b Mon Sep 17 00:00:00 2001 From: Doug Currie Date: Tue, 15 Nov 2016 17:49:18 -0500 Subject: [PATCH] fix issue #33 Negating most-negative-fixnum doesn't. (#35) * fix issue #33 Negating most-negative-fixnum doesn't. * Add unit test for issue #33 Negating most-negative-fixnum doesn't. --- cvalues.c | 6 +++++- flisp.c | 9 +++++++-- tests/unittest.lsp | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cvalues.c b/cvalues.c index 24db448..24fb829 100644 --- a/cvalues.c +++ b/cvalues.c @@ -1115,7 +1115,11 @@ static value_t fl_add_any(value_t *args, u_int32_t nargs, fixnum_t carryIn) static value_t fl_neg(value_t n) { if (isfixnum(n)) { - return fixnum(-numval(n)); + fixnum_t s = fixnum(-numval(n)); + if (__unlikely(s == n)) + return mk_long(-numval(n)); // negate overflows + else + return s; } else if (iscprim(n)) { cprim_t *cp = (cprim_t*)ptr(n); diff --git a/flisp.c b/flisp.c index f5c3f8d..4202b34 100644 --- a/flisp.c +++ b/flisp.c @@ -1396,8 +1396,13 @@ static value_t apply_cl(uint32_t nargs) NEXT_OP; OP(OP_NEG) do_neg: - if (isfixnum(Stack[SP-1])) - Stack[SP-1] = fixnum(-numval(Stack[SP-1])); + if (isfixnum(Stack[SP-1])) { + s = fixnum(-numval(Stack[SP-1])); + if (__unlikely(s == Stack[SP-1])) + Stack[SP-1] = mk_long(-numval(Stack[SP-1])); // negate overflows + else + Stack[SP-1] = s; + } else Stack[SP-1] = fl_neg(Stack[SP-1]); NEXT_OP; diff --git a/tests/unittest.lsp b/tests/unittest.lsp index 5748cb2..38891b0 100644 --- a/tests/unittest.lsp +++ b/tests/unittest.lsp @@ -65,6 +65,9 @@ (assert (> (- #int32(0x80000000)) 0)) (assert (< (- #uint64(0x8000000000000000)) 0)) (assert (> (- #int64(0x8000000000000000)) 0)) +; fixnum versions +(assert (= (- -536870912) 536870912)) +(assert (= (- -2305843009213693952) 2305843009213693952)) (assert (not (equal? #int64(0x8000000000000000) #uint64(0x8000000000000000)))) (assert (equal? (+ #int64(0x4000000000000000) #int64(0x4000000000000000))