Skip to content

Commit d076b3d

Browse files
committed
FIX: Math error when multiplying negative integer with zero integer
Fixes: #12
1 parent 6617792 commit d076b3d

File tree

2 files changed

+232
-6
lines changed

2 files changed

+232
-6
lines changed

src/core/f-int.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,15 @@ REBOOL reb_i64_mul_overflow(i64 x, i64 y, i64 *prod)
9898
REBFLG sgn;
9999
u64 p = 0;
100100

101+
if (y == 0 || x == 0) {
102+
*prod = 0;
103+
return FALSE;
104+
}
105+
101106
sgn = (x < 0);
102107
if (sgn) {
103108
if (x == MIN_I64) {
104109
switch (y) {
105-
case 0:
106-
*prod = 0;
107-
return 0;
108110
case 1:
109111
*prod = x;
110112
return 0;
@@ -118,9 +120,6 @@ REBOOL reb_i64_mul_overflow(i64 x, i64 y, i64 *prod)
118120
sgn = !sgn;
119121
if (y == MIN_I64) {
120122
switch (x) {
121-
case 0:
122-
*prod = 0;
123-
return 0;
124123
case 1:
125124
if (!sgn) {
126125
return 1;

src/tests/units/integer-test.r3

+227
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,232 @@ Rebol [
3030
--assert 0 = shift 1 -100
3131

3232
===end-group===
33+
34+
===start-group=== "multiply"
35+
--test-- "0 * 1"
36+
i: 0
37+
j: 1
38+
--assert strict-equal? 0 0 * 1
39+
--assert strict-equal? 0 multiply 0 1
40+
--assert strict-equal? 0 i * j
41+
--assert strict-equal? 0 multiply i j
42+
43+
--test-- "0 * -1"
44+
i: 0
45+
j: -1
46+
--assert strict-equal? 0 0 * -1
47+
--assert strict-equal? 0 multiply 0 -1
48+
--assert strict-equal? 0 i * j
49+
--assert strict-equal? 0 multiply i j
50+
51+
--test-- "0 * -2147483648"
52+
i: 0
53+
j: -2147483648
54+
--assert strict-equal? 0 0 * -2147483648
55+
--assert strict-equal? 0 multiply 0 -2147483648
56+
--assert strict-equal? 0 i * j
57+
--assert strict-equal? 0 multiply i j
58+
59+
--test-- "0 * 2147483647"
60+
i: 0
61+
j: 2147483647
62+
--assert strict-equal? 0 0 * 2147483647
63+
--assert strict-equal? 0 multiply 0 2147483647
64+
--assert strict-equal? 0 i * j
65+
--assert strict-equal? 0 multiply i j
66+
67+
--test-- "0 * 65536"
68+
i: 0
69+
j: 65536
70+
--assert strict-equal? 0 0 * 65536
71+
--assert strict-equal? 0 multiply 0 65536
72+
--assert strict-equal? 0 i * j
73+
--assert strict-equal? 0 multiply i j
74+
75+
--test-- "0 * 256"
76+
i: 0
77+
j: 256
78+
--assert strict-equal? 0 0 * 256
79+
--assert strict-equal? 0 multiply 0 256
80+
--assert strict-equal? 0 i * j
81+
--assert strict-equal? 0 multiply i j
82+
83+
--test-- "0 * 16777216"
84+
i: 0
85+
j: 16777216
86+
--assert strict-equal? 0 0 * 16777216
87+
--assert strict-equal? 0 multiply 0 16777216
88+
--assert strict-equal? 0 i * j
89+
--assert strict-equal? 0 multiply i j
90+
91+
--test-- "1 * -1"
92+
i: 1
93+
j: -1
94+
--assert strict-equal? -1 1 * -1
95+
--assert strict-equal? -1 multiply 1 -1
96+
--assert strict-equal? -1 i * j
97+
--assert strict-equal? -1 multiply i j
98+
99+
--test-- "1 * -2147483648"
100+
i: 1
101+
j: -2147483648
102+
--assert strict-equal? -2147483648 1 * -2147483648
103+
--assert strict-equal? -2147483648 multiply 1 -2147483648
104+
--assert strict-equal? -2147483648 i * j
105+
--assert strict-equal? -2147483648 multiply i j
106+
107+
--test-- "1 * 2147483647"
108+
i: 1
109+
j: 2147483647
110+
--assert strict-equal? 2147483647 1 * 2147483647
111+
--assert strict-equal? 2147483647 multiply 1 2147483647
112+
--assert strict-equal? 2147483647 i * j
113+
--assert strict-equal? 2147483647 multiply i j
114+
115+
--test-- "1 * 65536"
116+
i: 1
117+
j: 65536
118+
--assert strict-equal? 65536 1 * 65536
119+
--assert strict-equal? 65536 multiply 1 65536
120+
--assert strict-equal? 65536 i * j
121+
--assert strict-equal? 65536 multiply i j
122+
123+
--test-- "1 * 256"
124+
i: 1
125+
j: 256
126+
--assert strict-equal? 256 1 * 256
127+
--assert strict-equal? 256 multiply 1 256
128+
--assert strict-equal? 256 i * j
129+
--assert strict-equal? 256 multiply i j
130+
131+
--test-- "1 * 16777216"
132+
i: 1
133+
j: 16777216
134+
--assert strict-equal? 16777216 1 * 16777216
135+
--assert strict-equal? 16777216 multiply 1 16777216
136+
--assert strict-equal? 16777216 i * j
137+
--assert strict-equal? 16777216 multiply i j
138+
139+
--test-- "-1 * -2147483648"
140+
i: -1
141+
j: -2147483648
142+
--assert strict-equal? 2147483648 -1 * -2147483648
143+
--assert strict-equal? 2147483648 multiply -1 -2147483648
144+
--assert strict-equal? 2147483648 i * j
145+
--assert strict-equal? 2147483648 multiply i j
146+
147+
--test-- "-1 * 2147483647"strict-equal?
148+
i: -1
149+
j: 2147483647
150+
--assert strict-equal? -2147483647 -1 * 2147483647
151+
--assert strict-equal? -2147483647 multiply -1 2147483647
152+
--assert strict-equal? -2147483647 i * j
153+
--assert strict-equal? -2147483647 multiply i j
154+
155+
--test-- "-1 * 65536"
156+
i: -1
157+
j: 65536
158+
--assert strict-equal? -65536 -1 * 65536
159+
--assert strict-equal? -65536 multiply -1 65536
160+
--assert strict-equal? -65536 i * j
161+
--assert strict-equal? -65536 multiply i j
162+
163+
--test-- "-1 * 256"
164+
i: -1
165+
j: 256
166+
--assert strict-equal? -256 -1 * 256
167+
--assert strict-equal? -256 multiply -1 256
168+
--assert strict-equal? -256 i * j
169+
--assert strict-equal? -256 multiply i j
170+
171+
--test-- "-1 * 16777216"
172+
i: -1
173+
j: 16777216
174+
--assert strict-equal? -16777216 -1 * 16777216
175+
--assert strict-equal? -16777216 multiply -1 16777216
176+
--assert strict-equal? -16777216 i * j
177+
--assert strict-equal? -16777216 multiply i j
178+
179+
--test-- "-2147483648 * 2147483647"
180+
i: -2147483648
181+
j: 2147483647
182+
--assert strict-equal? -4611686016279904256 -2147483648 * 2147483647
183+
--assert strict-equal? -4611686016279904256 multiply -2147483648 2147483647
184+
--assert strict-equal? -4611686016279904256 i * j
185+
--assert strict-equal? -4611686016279904256 multiply i j
186+
187+
--test-- "-2147483648 * 65536"
188+
i: -2147483648
189+
j: 65536
190+
--assert strict-equal? -140737488355328 -2147483648 * 65536
191+
--assert strict-equal? -140737488355328 multiply -2147483648 65536
192+
--assert strict-equal? -140737488355328 i * j
193+
--assert strict-equal? -140737488355328 multiply i j
194+
195+
--test-- "-2147483648 * 256"
196+
i: -2147483648
197+
j: 256
198+
--assert strict-equal? -549755813888 -2147483648 * 256
199+
--assert strict-equal? -549755813888 multiply -2147483648 256
200+
--assert strict-equal? -549755813888 i * j
201+
--assert strict-equal? -549755813888 multiply i j
202+
203+
--test-- "-2147483648 * 16777216"
204+
i: -2147483648
205+
j: 16777216
206+
--assert strict-equal? -36028797018963968 -2147483648 * 16777216
207+
--assert strict-equal? -36028797018963968 multiply -2147483648 16777216
208+
--assert strict-equal? -36028797018963968 i * j
209+
--assert strict-equal? -36028797018963968 multiply i j
210+
211+
--test-- "2147483647 * 65536"
212+
i: 2147483647
213+
j: 65536
214+
--assert strict-equal? 140737488289792 2147483647 * 65536
215+
--assert strict-equal? 140737488289792 multiply 2147483647 65536
216+
--assert strict-equal? 140737488289792 i * j
217+
--assert strict-equal? 140737488289792 multiply i j
218+
219+
--test-- "2147483647 * 256"
220+
i: 2147483647
221+
j: 256
222+
--assert strict-equal? 549755813632 2147483647 * 256
223+
--assert strict-equal? 549755813632 multiply 2147483647 256
224+
--assert strict-equal? 549755813632 i * j
225+
--assert strict-equal? 549755813632 multiply i j
226+
227+
--test-- "2147483647 * 16777216"
228+
i: 2147483647
229+
j: 16777216
230+
--assert strict-equal? 36028797002186752 2147483647 * 16777216
231+
--assert strict-equal? 36028797002186752 multiply 2147483647 16777216
232+
--assert strict-equal? 36028797002186752 i * j
233+
--assert strict-equal? 36028797002186752 multiply i j
234+
235+
--test-- "65536 * 256"
236+
i: 65536
237+
j: 256
238+
--assert strict-equal? 16777216 65536 * 256
239+
--assert strict-equal? 16777216 multiply 65536 256
240+
--assert strict-equal? 16777216 i * j
241+
--assert strict-equal? 16777216 multiply i j
242+
243+
--test-- "65536 * 16777216"
244+
i: 65536
245+
j: 16777216
246+
--assert strict-equal? 1099511627776 65536 * 16777216
247+
--assert strict-equal? 1099511627776 multiply 65536 16777216
248+
--assert strict-equal? 1099511627776 i * j
249+
--assert strict-equal? 1099511627776 multiply i j
250+
251+
--test-- "256 * 16777216"
252+
i: 256
253+
j: 16777216
254+
--assert strict-equal? 4294967296 256 * 16777216
255+
--assert strict-equal? 4294967296 multiply 256 16777216
256+
--assert strict-equal? 4294967296 i * j
257+
--assert strict-equal? 4294967296 multiply i j
258+
259+
===end-group===
33260

34261
~~~end-file~~~

0 commit comments

Comments
 (0)