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.
This commit is contained in:
Doug Currie 2016-11-15 17:49:18 -05:00 committed by Jeff Bezanson
parent 6bc3fe5f11
commit 8342f9a1e9
3 changed files with 15 additions and 3 deletions

View File

@ -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) static value_t fl_neg(value_t n)
{ {
if (isfixnum(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)) { else if (iscprim(n)) {
cprim_t *cp = (cprim_t*)ptr(n); cprim_t *cp = (cprim_t*)ptr(n);

View File

@ -1396,8 +1396,13 @@ static value_t apply_cl(uint32_t nargs)
NEXT_OP; NEXT_OP;
OP(OP_NEG) OP(OP_NEG)
do_neg: do_neg:
if (isfixnum(Stack[SP-1])) if (isfixnum(Stack[SP-1])) {
Stack[SP-1] = fixnum(-numval(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 else
Stack[SP-1] = fl_neg(Stack[SP-1]); Stack[SP-1] = fl_neg(Stack[SP-1]);
NEXT_OP; NEXT_OP;

View File

@ -65,6 +65,9 @@
(assert (> (- #int32(0x80000000)) 0)) (assert (> (- #int32(0x80000000)) 0))
(assert (< (- #uint64(0x8000000000000000)) 0)) (assert (< (- #uint64(0x8000000000000000)) 0))
(assert (> (- #int64(0x8000000000000000)) 0)) (assert (> (- #int64(0x8000000000000000)) 0))
; fixnum versions
(assert (= (- -536870912) 536870912))
(assert (= (- -2305843009213693952) 2305843009213693952))
(assert (not (equal? #int64(0x8000000000000000) #uint64(0x8000000000000000)))) (assert (not (equal? #int64(0x8000000000000000) #uint64(0x8000000000000000))))
(assert (equal? (+ #int64(0x4000000000000000) #int64(0x4000000000000000)) (assert (equal? (+ #int64(0x4000000000000000) #int64(0x4000000000000000))