Skip to content

Commit

Permalink
FIX: Math error when multiplying negative integer with zero integer
Browse files Browse the repository at this point in the history
Fixes: #12
  • Loading branch information
Oldes committed Jan 20, 2020
1 parent 6617792 commit d076b3d
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 6 deletions.
11 changes: 5 additions & 6 deletions src/core/f-int.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,15 @@ REBOOL reb_i64_mul_overflow(i64 x, i64 y, i64 *prod)
REBFLG sgn;
u64 p = 0;

if (y == 0 || x == 0) {
*prod = 0;
return FALSE;
}

sgn = (x < 0);
if (sgn) {
if (x == MIN_I64) {
switch (y) {
case 0:
*prod = 0;
return 0;
case 1:
*prod = x;
return 0;
Expand All @@ -118,9 +120,6 @@ REBOOL reb_i64_mul_overflow(i64 x, i64 y, i64 *prod)
sgn = !sgn;
if (y == MIN_I64) {
switch (x) {
case 0:
*prod = 0;
return 0;
case 1:
if (!sgn) {
return 1;
Expand Down
227 changes: 227 additions & 0 deletions src/tests/units/integer-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,232 @@ Rebol [
--assert 0 = shift 1 -100

===end-group===

===start-group=== "multiply"
--test-- "0 * 1"
i: 0
j: 1
--assert strict-equal? 0 0 * 1
--assert strict-equal? 0 multiply 0 1
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * -1"
i: 0
j: -1
--assert strict-equal? 0 0 * -1
--assert strict-equal? 0 multiply 0 -1
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * -2147483648"
i: 0
j: -2147483648
--assert strict-equal? 0 0 * -2147483648
--assert strict-equal? 0 multiply 0 -2147483648
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * 2147483647"
i: 0
j: 2147483647
--assert strict-equal? 0 0 * 2147483647
--assert strict-equal? 0 multiply 0 2147483647
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * 65536"
i: 0
j: 65536
--assert strict-equal? 0 0 * 65536
--assert strict-equal? 0 multiply 0 65536
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * 256"
i: 0
j: 256
--assert strict-equal? 0 0 * 256
--assert strict-equal? 0 multiply 0 256
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "0 * 16777216"
i: 0
j: 16777216
--assert strict-equal? 0 0 * 16777216
--assert strict-equal? 0 multiply 0 16777216
--assert strict-equal? 0 i * j
--assert strict-equal? 0 multiply i j

--test-- "1 * -1"
i: 1
j: -1
--assert strict-equal? -1 1 * -1
--assert strict-equal? -1 multiply 1 -1
--assert strict-equal? -1 i * j
--assert strict-equal? -1 multiply i j

--test-- "1 * -2147483648"
i: 1
j: -2147483648
--assert strict-equal? -2147483648 1 * -2147483648
--assert strict-equal? -2147483648 multiply 1 -2147483648
--assert strict-equal? -2147483648 i * j
--assert strict-equal? -2147483648 multiply i j

--test-- "1 * 2147483647"
i: 1
j: 2147483647
--assert strict-equal? 2147483647 1 * 2147483647
--assert strict-equal? 2147483647 multiply 1 2147483647
--assert strict-equal? 2147483647 i * j
--assert strict-equal? 2147483647 multiply i j

--test-- "1 * 65536"
i: 1
j: 65536
--assert strict-equal? 65536 1 * 65536
--assert strict-equal? 65536 multiply 1 65536
--assert strict-equal? 65536 i * j
--assert strict-equal? 65536 multiply i j

--test-- "1 * 256"
i: 1
j: 256
--assert strict-equal? 256 1 * 256
--assert strict-equal? 256 multiply 1 256
--assert strict-equal? 256 i * j
--assert strict-equal? 256 multiply i j

--test-- "1 * 16777216"
i: 1
j: 16777216
--assert strict-equal? 16777216 1 * 16777216
--assert strict-equal? 16777216 multiply 1 16777216
--assert strict-equal? 16777216 i * j
--assert strict-equal? 16777216 multiply i j

--test-- "-1 * -2147483648"
i: -1
j: -2147483648
--assert strict-equal? 2147483648 -1 * -2147483648
--assert strict-equal? 2147483648 multiply -1 -2147483648
--assert strict-equal? 2147483648 i * j
--assert strict-equal? 2147483648 multiply i j

--test-- "-1 * 2147483647"strict-equal?
i: -1
j: 2147483647
--assert strict-equal? -2147483647 -1 * 2147483647
--assert strict-equal? -2147483647 multiply -1 2147483647
--assert strict-equal? -2147483647 i * j
--assert strict-equal? -2147483647 multiply i j

--test-- "-1 * 65536"
i: -1
j: 65536
--assert strict-equal? -65536 -1 * 65536
--assert strict-equal? -65536 multiply -1 65536
--assert strict-equal? -65536 i * j
--assert strict-equal? -65536 multiply i j

--test-- "-1 * 256"
i: -1
j: 256
--assert strict-equal? -256 -1 * 256
--assert strict-equal? -256 multiply -1 256
--assert strict-equal? -256 i * j
--assert strict-equal? -256 multiply i j

--test-- "-1 * 16777216"
i: -1
j: 16777216
--assert strict-equal? -16777216 -1 * 16777216
--assert strict-equal? -16777216 multiply -1 16777216
--assert strict-equal? -16777216 i * j
--assert strict-equal? -16777216 multiply i j

--test-- "-2147483648 * 2147483647"
i: -2147483648
j: 2147483647
--assert strict-equal? -4611686016279904256 -2147483648 * 2147483647
--assert strict-equal? -4611686016279904256 multiply -2147483648 2147483647
--assert strict-equal? -4611686016279904256 i * j
--assert strict-equal? -4611686016279904256 multiply i j

--test-- "-2147483648 * 65536"
i: -2147483648
j: 65536
--assert strict-equal? -140737488355328 -2147483648 * 65536
--assert strict-equal? -140737488355328 multiply -2147483648 65536
--assert strict-equal? -140737488355328 i * j
--assert strict-equal? -140737488355328 multiply i j

--test-- "-2147483648 * 256"
i: -2147483648
j: 256
--assert strict-equal? -549755813888 -2147483648 * 256
--assert strict-equal? -549755813888 multiply -2147483648 256
--assert strict-equal? -549755813888 i * j
--assert strict-equal? -549755813888 multiply i j

--test-- "-2147483648 * 16777216"
i: -2147483648
j: 16777216
--assert strict-equal? -36028797018963968 -2147483648 * 16777216
--assert strict-equal? -36028797018963968 multiply -2147483648 16777216
--assert strict-equal? -36028797018963968 i * j
--assert strict-equal? -36028797018963968 multiply i j

--test-- "2147483647 * 65536"
i: 2147483647
j: 65536
--assert strict-equal? 140737488289792 2147483647 * 65536
--assert strict-equal? 140737488289792 multiply 2147483647 65536
--assert strict-equal? 140737488289792 i * j
--assert strict-equal? 140737488289792 multiply i j

--test-- "2147483647 * 256"
i: 2147483647
j: 256
--assert strict-equal? 549755813632 2147483647 * 256
--assert strict-equal? 549755813632 multiply 2147483647 256
--assert strict-equal? 549755813632 i * j
--assert strict-equal? 549755813632 multiply i j

--test-- "2147483647 * 16777216"
i: 2147483647
j: 16777216
--assert strict-equal? 36028797002186752 2147483647 * 16777216
--assert strict-equal? 36028797002186752 multiply 2147483647 16777216
--assert strict-equal? 36028797002186752 i * j
--assert strict-equal? 36028797002186752 multiply i j

--test-- "65536 * 256"
i: 65536
j: 256
--assert strict-equal? 16777216 65536 * 256
--assert strict-equal? 16777216 multiply 65536 256
--assert strict-equal? 16777216 i * j
--assert strict-equal? 16777216 multiply i j

--test-- "65536 * 16777216"
i: 65536
j: 16777216
--assert strict-equal? 1099511627776 65536 * 16777216
--assert strict-equal? 1099511627776 multiply 65536 16777216
--assert strict-equal? 1099511627776 i * j
--assert strict-equal? 1099511627776 multiply i j

--test-- "256 * 16777216"
i: 256
j: 16777216
--assert strict-equal? 4294967296 256 * 16777216
--assert strict-equal? 4294967296 multiply 256 16777216
--assert strict-equal? 4294967296 i * j
--assert strict-equal? 4294967296 multiply i j

===end-group===

~~~end-file~~~

0 comments on commit d076b3d

Please sign in to comment.