/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- message
- test_uadd
- test_uaddov
- test_saddov
- test_usub
- test_usubov
- test_ssubov
- test_umul
- test_umulov
- test_smulov
- test_scm_c_scm
- test_true
- test_32_64
- main
1 /*
2 * Test the lowest-level numeric routines.
3 * $Id: test-arith.c,v 1.6 2004/11/05 10:33:39 shirok Exp $
4 */
5
6 #include <stdio.h>
7 #include "gauche.h"
8 #include "gauche/arith.h"
9 #include "gauche/scmconst.h"
10
11 #define UMAX SCM_ULONG_MAX
12 #define SMAX LONG_MAX
13 #define SMIN LONG_MIN
14
15 int errcount = 0;
16
17 void message(FILE *out, const char *m, int filler)
18 {
19 int i;
20 fprintf(out, "%s", m);
21 if (filler) {
22 int len = 79 - strlen(m);
23 if (len < 0) len = 5;
24 for (i=0; i<len; i++) putc(filler, out);
25 }
26 putc('\n', out);
27 }
28
29 /*=============================================================
30 * Testing macros in gauche/arith.h
31 */
32
33 #define TEST_SECTION(name) message(stdout, "<" name ">", '-')
34
35 #define TEST5(x_, y_, c_, rexp, cexp, numfmt, opmsg, op) \
36 do { \
37 printf("testing " numfmt opmsg numfmt " c=" numfmt \
38 " expects r=" numfmt ", c=" numfmt " =>", \
39 x_, y_, c_, rexp, cexp); \
40 c = c_; \
41 x = x_; \
42 y = y_; \
43 op(r, c, x, y); \
44 if (r == rexp && c == cexp) { \
45 printf("ok\n"); \
46 } else { \
47 errcount++; \
48 printf("ERROR: got r=" numfmt \
49 ", c=" numfmt "\n", r, c); \
50 } \
51 } while (0)
52
53 #define TESTOV(x_, y_, rexp, cexp, numfmt, opmsg, op) \
54 do { \
55 x = x_; \
56 y = y_; \
57 if (cexp) \
58 printf("testing " numfmt opmsg numfmt \
59 " expects overflow =>", x_, y_); \
60 else \
61 printf("testing " numfmt opmsg numfmt \
62 " expects " numfmt " =>", x_, y_, rexp); \
63 op(r, c, x, y); \
64 if (c) { \
65 if (cexp == c) printf("ok\n"); \
66 else { \
67 errcount++; \
68 printf("ERROR: got r=" numfmt \
69 ", c=" numfmt "\n", r, c); \
70 } \
71 } else { \
72 if (r == rexp) printf("ok\n"); \
73 else { \
74 errcount++; \
75 printf("ERROR: got r=" numfmt "\n", r); \
76 } \
77 } \
78 } while (0)
79
80 /*
81 * UADD
82 */
83 #define TEST_UADD(x_, y_, c_, rexp, cexp) \
84 TEST5(x_, y_, c_, rexp, cexp, "%u", "+", UADD)
85
86 void test_uadd(void)
87 {
88 u_long r, c, x, y;
89 TEST_SECTION("UADD");
90
91 /* MAX + 0 + 0 => [MAX, 0] */
92 TEST_UADD(UMAX, 0, 0, UMAX, 0);
93 /* MAX + 1 + 0 => [0, 1] */
94 TEST_UADD(UMAX, 1, 0, 0, 1);
95 /* MAX + 2 + 0 => [1, 1] */
96 TEST_UADD(UMAX, 2, 0, 1, 1);
97 /* MAX + MAX + 0 => [MAX-1, 1] */
98 TEST_UADD(UMAX, UMAX, 0, UMAX-1, 1);
99 /* MAX/2 + MAX/2 + 0 => [MAX-1, 0] */
100 TEST_UADD(UMAX/2, UMAX/2, 0, UMAX-1, 0);
101 /* MAX/2 + MAX + 0 => [MAX/2-1, 1] */
102 TEST_UADD(UMAX/2, UMAX, 0, UMAX/2-1, 1);
103 /* MAX-1 + 0 + 1 => [MAX, 0] */
104 TEST_UADD(UMAX-1, 0, 1, UMAX, 0);
105 /* MAX + 0 + 1 => [0, 1] */
106 TEST_UADD(UMAX, 0, 1, 0, 1);
107 /* MAX + 1 + 1 => [1, 1] */
108 TEST_UADD(UMAX, 1, 1, 1, 1);
109 /* MAX + MAX + 1 => [MAX, 1] */
110 TEST_UADD(UMAX, UMAX, 1, UMAX, 1);
111 /* MAX/2 + MAX/2 + 1 => [MAX, 0] */
112 TEST_UADD(UMAX/2, UMAX/2, 1, UMAX, 0);
113 /* MAX/2 + MAX + 1 => [MAX/2, 1] */
114 TEST_UADD(UMAX/2, UMAX, 1, UMAX/2, 1);
115 }
116
117 /*
118 * UADDOV
119 */
120 #define TEST_UADDOV(x_, y_, rexp, cexp) \
121 TESTOV(x_, y_, rexp, cexp, "%u", "+", UADDOV)
122
123 void test_uaddov(void)
124 {
125 u_long r, c, x, y;
126 TEST_SECTION("UADDOV");
127
128 /* MAX + 0 => MAX */
129 TEST_UADDOV(UMAX, 0, UMAX, 0);
130 /* MAX + 1 => overflow */
131 TEST_UADDOV(UMAX, 1, 0, 1);
132 /* MAX + 2 => overflow */
133 TEST_UADDOV(UMAX, 2, 0, 1);
134 /* MAX + MAX => overflow */
135 TEST_UADDOV(UMAX, UMAX, 0, 1);
136 /* MAX/2 + MAX/2 => MAX-1, 0 */
137 TEST_UADDOV(UMAX/2, UMAX/2, UMAX-1, 0);
138 /* MAX/2 + MAX => overflow */
139 TEST_UADDOV(UMAX/2, UMAX, 0, 1);
140 /* MAX-1 + 1 => MAX */
141 TEST_UADDOV(UMAX-1, 1, UMAX, 0);
142 /* MAX-1 + 2 => overflow */
143 TEST_UADDOV(UMAX-1, 2, 0, 1);
144 }
145
146 /*
147 * SADDOV
148 */
149 #define TEST_SADDOV(x_, y_, rexp, cexp) \
150 TESTOV(x_, y_, rexp, cexp, "%ld", "+", SADDOV)
151
152 void test_saddov(void)
153 {
154 long r, c, x, y;
155 TEST_SECTION("SADDOV");
156
157 /* 1 + 1 => 2 */
158 TEST_SADDOV(1, 1, 2, 0);
159 /* -1 + -1 => -2 */
160 TEST_SADDOV(-1, -1, -2, 0);
161 /* SMAX + 0 => SMAX */
162 TEST_SADDOV(SMAX, 0, SMAX, 0);
163 /* SMAX + 1 => overflow */
164 TEST_SADDOV(SMAX, 1, 0, 1);
165 /* SMAX + 2 => overflow */
166 TEST_SADDOV(SMAX, 2, 0, 1);
167 /* SMAX + -1 => SMAX-1 */
168 TEST_SADDOV(SMAX, -1, SMAX-1, 0);
169 /* SMAX + -SMAX => 0 */
170 TEST_SADDOV(SMAX, -SMAX, 0, 0);
171 /* SMAX + -SMAX-1 => -1 */
172 TEST_SADDOV(SMAX, -SMAX-1, -1, 0);
173 /* SMAX/2 + SMAX/2 => SMAX-1 */
174 TEST_SADDOV(SMAX/2, SMAX/2, SMAX-1, 0);
175 /* SMAX/2 + -SMAX/2 => 0 */
176 TEST_SADDOV(SMAX/2, -(SMAX/2), 0, 0);
177 /* -SMAX/2 + -SMAX/2 => -(SMAX-1) */
178 TEST_SADDOV(-(SMAX/2), -(SMAX/2), -(SMAX-1), 0);
179 /* 0 + -SMAX => -SMAX */
180 TEST_SADDOV(0, -SMAX, -SMAX, 0);
181 /* -1 + -SMAX => SMIN */
182 TEST_SADDOV(-1, -SMAX, SMIN, 0);
183 /* -2 + -SMAX => -overflow */
184 TEST_SADDOV(-2, -SMAX, 0, -1);
185 /* -SMAX + -2 => -overflow */
186 TEST_SADDOV(-SMAX, -2, 0, -1);
187 /* -SMAX + -SMAX => -overflow */
188 TEST_SADDOV(-SMAX, -SMAX, 0, -1);
189 /* -SMAX + SMIN => -overflow */
190 TEST_SADDOV(-SMAX, SMIN, 0, -1);
191 }
192
193 /*
194 * USUB
195 */
196 #define TEST_USUB(x_, y_, c_, rexp, cexp) \
197 TEST5(x_, y_, c_, rexp, cexp, "%u", "-", USUB)
198
199 void test_usub(void)
200 {
201 u_long r, c, x, y;
202 TEST_SECTION("USUB");
203
204 /* MAX - 0 - 0 => [MAX, 0] */
205 TEST_USUB(UMAX, 0, 0, UMAX, 0);
206 /* MAX - 1 - 0 => [MAX-1, 0] */
207 TEST_USUB(UMAX, 1, 0, UMAX-1, 0);
208 /* 0 - MAX - 0 => [1, 1] */
209 TEST_USUB(0, UMAX, 0, 1, 1);
210 /* 1 - MAX - 0 => [2, 1] */
211 TEST_USUB(1, UMAX, 0, 2, 1);
212 /* MAX - MAX/2 - 0 => [MAX/2+1, 0] */
213 TEST_USUB(UMAX, UMAX/2, 0, UMAX/2+1, 0);
214 /* MAX/2 - MAX - 0 => [MAX/2+1, 1] */
215 TEST_USUB(UMAX/2, UMAX, 0, UMAX/2+1, 1);
216 /* MAX - 0 - 1 => [MAX-1, 0] */
217 TEST_USUB(UMAX, 0, 1, UMAX-1, 0);
218 /* MAX - 1 - 1 => [MAX-2, 0] */
219 TEST_USUB(UMAX, 1, 1, UMAX-2, 0);
220 /* 0 - MAX - 1 => [0, 1] */
221 TEST_USUB(0, UMAX, 1, 0, 1);
222 /* 1 - MAX - 1 => [1, 1] */
223 TEST_USUB(1, UMAX, 1, 1, 1);
224 /* MAX - MAX/2 - 1 => [MAX/2, 0] */
225 TEST_USUB(UMAX, UMAX/2, 1, UMAX/2, 0);
226 /* MAX/2 - MAX - 1 => [MAX/2, 1] */
227 TEST_USUB(UMAX/2, UMAX, 1, UMAX/2, 1);
228 }
229
230 /*
231 * USUBOV
232 */
233 #define TEST_USUBOV(x_, y_, rexp, cexp) \
234 TESTOV(x_, y_, rexp, cexp, "%u", "-", USUBOV)
235
236 void test_usubov(void)
237 {
238 u_long r, c, x, y;
239 TEST_SECTION("USUBOV");
240
241 /* MAX - 0 => MAX */
242 TEST_USUBOV(UMAX, 0, UMAX, 0);
243 /* MAX - 1 => MAX-1 */
244 TEST_USUBOV(UMAX, 1, UMAX-1, 0);
245 /* MAX - MAX => 0 */
246 TEST_USUBOV(UMAX, UMAX, 0, 0);
247 /* MAX-1 - MAX => overflow */
248 TEST_USUBOV(UMAX-1, UMAX, 0, 1);
249 /* MAX - MAX-1 => 1 */
250 TEST_USUBOV(UMAX, UMAX-1, 1, 0);
251 /* 0 - 1 => overflow */
252 TEST_USUBOV(0, 1, 0, 1);
253 /* 0 - MAX => overflow */
254 TEST_USUBOV(0, UMAX, 0, 1);
255 }
256
257 /*
258 * SSUBOV
259 */
260 #define TEST_SSUBOV(x_, y_, rexp, cexp) \
261 TESTOV(x_, y_, rexp, cexp, "%ld", "-", SSUBOV)
262
263 void test_ssubov(void)
264 {
265 long r, c, x, y;
266 TEST_SECTION("SSUBOV");
267
268 /* 1 - 1 => 0 */
269 TEST_SSUBOV(1, 1, 0, 0);
270 /* -1 - -1 => 0 */
271 TEST_SSUBOV(-1, -1, 0, 0);
272 /* SMAX - 0 => SMAX */
273 TEST_SSUBOV(SMAX, 0, SMAX, 0);
274 /* SMAX - 1 => SMAX-1 */
275 TEST_SSUBOV(SMAX, 1, SMAX-1, 0);
276 /* SMAX - -1 => overflow */
277 TEST_SSUBOV(SMAX, -1, 0, 1);
278 /* SMAX - -2 => overflow */
279 TEST_SSUBOV(SMAX, -2, 0, 1);
280 /* SMAX - -SMAX => overflow */
281 TEST_SSUBOV(SMAX, -SMAX, 0, 1);
282 /* SMAX - SMAX => 0 */
283 TEST_SSUBOV(SMAX, SMAX, 0, 0);
284 /* SMAX/2 - -SMAX/2 => SMAX-1 */
285 TEST_SSUBOV(SMAX/2, -(SMAX/2), SMAX-1, 0);
286 /* SMAX/2 - SMAX/2 => 0 */
287 TEST_SSUBOV(SMAX/2, SMAX/2, 0, 0);
288 /* -SMAX/2 - SMAX/2 => 0 */
289 TEST_SSUBOV(-(SMAX/2), SMAX/2, -(SMAX-1), 0);
290 /* 0 - -SMAX => SMAX */
291 TEST_SSUBOV(0, -SMAX, SMAX, 0);
292 /* 1 - -SMAX => overflow */
293 TEST_SSUBOV(1, -SMAX, 0, 1);
294 /* 0 - -SMAX => SMAX */
295 TEST_SSUBOV(0, -SMAX, SMAX, 0);
296 /* SMIN - 1 => -overflow */
297 TEST_SSUBOV(SMIN, 1, 0, -1);
298 /* SMIN - -1 => SMIN+1 */
299 TEST_SSUBOV(SMIN, -1, SMIN+1, 0);
300 /* -SMAX - -SMAX => 0 */
301 TEST_SSUBOV(-SMAX, -SMAX, 0, 0);
302 /* -SMAX - SMIN => 1 */
303 TEST_SSUBOV(-SMAX, SMIN, 1, 0);
304 }
305
306 /*
307 * UMUL
308 */
309 #define TEST_UMUL(x_, y_, hiexp, loexp) \
310 do { \
311 printf("testing %u*%u expects hi=%u, lo=%u =>", x_, y_, \
312 hiexp, loexp); \
313 x = x_; \
314 y = y_; \
315 UMUL(hi, lo, x, y); \
316 if (hi == hiexp && lo == loexp) { \
317 printf("ok\n"); \
318 } else { \
319 errcount++; \
320 printf("ERROR: got hi=%u, lo=%u\n", hi, lo); \
321 } \
322 } while (0)
323
324 void test_umul(void)
325 {
326 u_long hi, lo, x, y;
327 TEST_SECTION("UMUL");
328
329 /* MAX * MAX => [MAX-1, 1] */
330 TEST_UMUL(UMAX, UMAX, UMAX-1, 1);
331 /* MAX-1 * MAX-1 => [MAX-3, 4] */
332 TEST_UMUL(UMAX-1, UMAX-1, UMAX-3, 4);
333 /* MAX/2 * 2 => [0, MAX-1] */
334 TEST_UMUL(UMAX/2, 2, 0, UMAX-1);
335 /* MAX/2+1 * 2 => [1, 0] */
336 TEST_UMUL(UMAX/2+1, 2, 1, 0);
337 }
338
339 /*
340 * UMULOV
341 */
342 #define TEST_UMULOV(x_, y_, rexp, cexp) \
343 TESTOV(x_, y_, rexp, cexp, "%lu", "*", UMULOV)
344
345 void test_umulov(void)
346 {
347 u_long r, c, x, y;
348 TEST_SECTION("UMULOV");
349
350 /* 0 * 1 => 0 */
351 TEST_UMULOV(0, 1, 0, 0);
352 /* 1 * 0 => 0 */
353 TEST_UMULOV(1, 0, 0, 0);
354 /* 1 * 1 => 1 */
355 TEST_UMULOV(1, 1, 1, 0);
356 /* 1 * UMAX => UMAX */
357 TEST_UMULOV(1, UMAX, UMAX, 0);
358 /* 2 * UMAX => overflow */
359 TEST_UMULOV(2, UMAX, 0, 1);
360 /* UMAX/2 * 2 => UMAX-1 */
361 TEST_UMULOV(UMAX/2, 2, UMAX-1, 0);
362 /* UMAX/2 * 3 => overflow */
363 TEST_UMULOV(UMAX/2, 3, 0, 1);
364 /* UMAX>>4 * UMAX>>4 => overflow */
365 TEST_UMULOV((UMAX>>4), (UMAX>>4), 0, 1);
366 /* UMAX>>8 * UMAX>>8 => overflow */
367 TEST_UMULOV((UMAX>>8), (UMAX>>8), 0, 1);
368 /* UMAX * UMAX => overflow */
369 TEST_UMULOV(UMAX, UMAX, 0, 1);
370 /* UMAX-1 * UMAX-1 => overflow */
371 TEST_UMULOV(UMAX-1, UMAX-1, 0, 1);
372 }
373
374 /*
375 * SMULOV
376 */
377 #define TEST_SMULOV(x_, y_, rexp, cexp) \
378 TESTOV(x_, y_, rexp, cexp, "%ld", "*", SMULOV)
379
380 void test_smulov(void)
381 {
382 long r, c, x, y;
383 TEST_SECTION("SMULOV");
384
385 /* 0 * 1 => 0 */
386 TEST_SMULOV(0, 1, 0, 0);
387 /* 1 * 0 => 0 */
388 TEST_SMULOV(1, 0, 0, 0);
389 /* 1 * 1 => 1 */
390 TEST_SMULOV(1, 1, 1, 0);
391 /* 1 * -1 => -1 */
392 TEST_SMULOV(1, -1, -1, 0);
393 /* -1 * 1 => -1 */
394 TEST_SMULOV(-1, 1, -1, 0);
395 /* -1 * -1 => 1 */
396 TEST_SMULOV(-1, -1, 1, 0);
397 /* 1 * SMAX => SMAX */
398 TEST_SMULOV(1, SMAX, SMAX, 0);
399 /* 1 * -SMAX => -SMAX */
400 TEST_SMULOV(1, -SMAX, -SMAX, 0);
401 /* -1 * SMAX => -SMAX */
402 TEST_SMULOV(-1, SMAX, -SMAX, 0);
403 /* -1 * -SMAX => SMAX */
404 TEST_SMULOV(-1, -SMAX, SMAX, 0);
405 /* 1 * SMIN => SMIN */
406 TEST_SMULOV(1, SMIN, SMIN, 0);
407 /* -1 * SMIN => overflow */
408 TEST_SMULOV(-1, SMIN, 0, 1);
409 /* 2 * SMAX => overflow */
410 TEST_SMULOV(2, SMAX, 0, 1);
411 /* 2 * -SMAX => -overflow */
412 TEST_SMULOV(2, -SMAX, 0, -1);
413 /* -2 * SMAX => -overflow */
414 TEST_SMULOV(-2, SMAX, 0, -1);
415 /* -2 * -SMAX => overflow */
416 TEST_SMULOV(-2, -SMAX, 0, 1);
417 /* SMAX/2 * 2 => SMAX-1 */
418 TEST_SMULOV(SMAX/2, 2, SMAX-1, 0);
419 /* SMAX/2 * -2 => -(SMAX-1) */
420 TEST_SMULOV(SMAX/2, -2, -(SMAX-1), 0);
421 /* -SMAX/2 * 2 => -(SMAX-1) */
422 TEST_SMULOV(-(SMAX/2), 2, -(SMAX-1), 0);
423 /* -SMAX/2 * -2 => SMAX-1 */
424 TEST_SMULOV(-(SMAX/2), -2, SMAX-1, 0);
425 /* SMAX/2+1 * 2 => overflow */
426 TEST_SMULOV(SMAX/2+1, 2, 0, 1);
427 /* SMAX/2+1 * -2 => SMIN */
428 TEST_SMULOV(SMAX/2+1, -2, SMIN, 0);
429 /* -(SMAX/2+1) * 2 => SMIN */
430 TEST_SMULOV(-(SMAX/2+1), 2, SMIN, 0);
431 /* -(SMAX/2+1) * -2 => overflow */
432 TEST_SMULOV(-(SMAX/2+1), -2, 0, 1);
433 /* SMAX>>4 * SMAX>>4 => overflow */
434 TEST_SMULOV((SMAX>>4), (SMAX>>4), 0, 1);
435 /* SMAX>>4 * -SMAX>>4 => -overflow */
436 TEST_SMULOV((SMAX>>4), -(SMAX>>4), 0, -1);
437 /* -SMAX>>4 * SMAX>>4 => -overflow */
438 TEST_SMULOV(-(SMAX>>4), (SMAX>>4), 0, -1);
439 /* -SMAX>>4 * -SMAX>>4 => overflow */
440 TEST_SMULOV(-(SMAX>>4), -(SMAX>>4), 0, 1);
441 /* SMAX>>8 * SMAX>>8 => overflow */
442 TEST_SMULOV((SMAX>>8), (SMAX>>8), 0, 1);
443 /* SMAX>>8 * -SMAX>>8 => -overflow */
444 TEST_SMULOV((SMAX>>8), -(SMAX>>8), 0, -1);
445 /* -SMAX>>8 * SMAX>>8 => -overflow */
446 TEST_SMULOV(-(SMAX>>8), (SMAX>>8), 0, -1);
447 /* -SMAX>>8 * -SMAX>>8 => overflow */
448 TEST_SMULOV(-(SMAX>>8), -(SMAX>>8), 0, 1);
449 /* SMAX * SMAX => overflow */
450 TEST_SMULOV(SMAX, SMAX, 0, 1);
451 /* SMAX * -SMAX => -overflow */
452 TEST_SMULOV(SMAX, -SMAX, 0, -1);
453 /* -SMAX * SMAX => -overflow */
454 TEST_SMULOV(-SMAX, SMAX, 0, -1);
455 /* -SMAX * -SMAX => overflow */
456 TEST_SMULOV(-SMAX, -SMAX, 0, 1);
457 }
458
459 /*=============================================================
460 * Testing 32/64-bit conversion routines
461 */
462
463 int test_scm_c_scm(const char *msg, ScmObj expect, ScmObj val)
464 {
465 Scm_Printf(SCM_CUROUT, "testing %s, expects %S =>", msg, expect);
466 if (Scm_EqualP(expect, val)) {
467 Scm_Printf(SCM_CUROUT, "ok\n");
468 } else {
469 Scm_Printf(SCM_CUROUT, "ERROR: got %S\n", val);
470 errcount++;
471 }
472 }
473
474 int test_true(const char *msg, int val)
475 {
476 Scm_Printf(SCM_CUROUT, "testing %s, expects TRUE =>", msg);
477 if (val) {
478 Scm_Printf(SCM_CUROUT, "ok\n");
479 } else {
480 Scm_Printf(SCM_CUROUT, "ERROR: got %d\n", val);
481 errcount++;
482 }
483 }
484
485
486
487 int test_32_64(void)
488 {
489 ScmObj vv;
490 int oor;
491
492 TEST_SECTION("integer conversions, non clamping");
493
494 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1));
495 test_scm_c_scm("long roundtrip 2^31-1", vv,
496 Scm_MakeInteger(Scm_GetInteger(vv)));
497 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-3));
498 test_scm_c_scm("long roundtrip 2^31-3", vv,
499 Scm_MakeInteger(Scm_GetInteger(vv)));
500 vv = Scm_Negate(SCM_2_31);
501 test_scm_c_scm("long roundtrip -2^31", vv,
502 Scm_MakeInteger(Scm_GetInteger(vv)));
503 vv = Scm_Add2(Scm_Negate(SCM_2_31), SCM_MAKE_INT(2));
504 test_scm_c_scm("long roundtrip -2^31+2", vv,
505 Scm_MakeInteger(Scm_GetInteger(vv)));
506 #if SIZEOF_LONG >= 8
507 vv = Scm_Add2(SCM_2_63, SCM_MAKE_INT(-1));
508 test_scm_c_scm("long roundtrip 2^63-1", vv,
509 Scm_MakeInteger(Scm_GetInteger(vv)));
510 vv = Scm_Add2(SCM_2_63, SCM_MAKE_INT(-3));
511 test_scm_c_scm("long roundtrip 2^63-3", vv,
512 Scm_MakeInteger(Scm_GetInteger(vv)));
513 vv = Scm_Negate(SCM_2_63);
514 test_scm_c_scm("long roundtrip -2^63", vv,
515 Scm_MakeInteger(Scm_GetInteger(vv)));
516 vv = Scm_Add2(Scm_Negate(SCM_2_63), SCM_MAKE_INT(2));
517 test_scm_c_scm("long roundtrip -2^63+2", vv,
518 Scm_MakeInteger(Scm_GetInteger(vv)));
519 #endif
520 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-1));
521 test_scm_c_scm("u_long roundtrip 2^31-1", vv,
522 Scm_MakeIntegerU(Scm_GetIntegerU(vv)));
523 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-3));
524 test_scm_c_scm("u_long roundtrip 2^31-3", vv,
525 Scm_MakeIntegerU(Scm_GetIntegerU(vv)));
526 #if SIZEOF_LONG >= 8
527 vv = Scm_Add2(SCM_2_64, SCM_MAKE_INT(-1));
528 test_scm_c_scm("u_long roundtrip 2^64-1", vv,
529 Scm_MakeIntegerU(Scm_GetIntegerU(vv)));
530 vv = Scm_Add2(SCM_2_64, SCM_MAKE_INT(-3));
531 test_scm_c_scm("u_long roundtrip 2^64-3", vv,
532 Scm_MakeIntegerU(Scm_GetIntegerU(vv)));
533 #endif
534
535 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1));
536 test_scm_c_scm("ScmInt32 roundtrip 2^31-1", vv,
537 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, 0, NULL)));
538 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-3));
539 test_scm_c_scm("ScmInt32 roundtrip 2^31-3", vv,
540 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, 0, NULL)));
541 vv = Scm_Negate(SCM_2_31);
542 test_scm_c_scm("ScmInt32 roundtrip -2^31", vv,
543 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, 0, NULL)));
544 vv = Scm_Add2(Scm_Negate(SCM_2_31), SCM_MAKE_INT(2));
545 test_scm_c_scm("ScmInt32 roundtrip -2^31+2", vv,
546 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, 0, NULL)));
547 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-1));
548 test_scm_c_scm("ScmUInt32 roundtrip 2^32-1", vv,
549 Scm_MakeIntegerU(Scm_GetIntegerU32Clamp(vv, 0, NULL)));
550 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-3));
551 test_scm_c_scm("ScmUInt32 roundtrip 2^32-3", vv,
552 Scm_MakeIntegerU(Scm_GetIntegerU32Clamp(vv, 0, NULL)));
553
554 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1));
555 test_scm_c_scm("ScmInt64 roundtrip 2^31-1", vv,
556 Scm_MakeInteger64(Scm_GetInteger64(vv)));
557 vv = SCM_2_31;
558 test_scm_c_scm("ScmInt64 roundtrip 2^31", vv,
559 Scm_MakeInteger64(Scm_GetInteger64(vv)));
560 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-1));
561 test_scm_c_scm("ScmInt64 roundtrip 2^32-1", vv,
562 Scm_MakeInteger64(Scm_GetInteger64(vv)));
563 vv = SCM_2_32;
564 test_scm_c_scm("ScmInt64 roundtrip 2^32", vv,
565 Scm_MakeInteger64(Scm_GetInteger64(vv)));
566
567 vv = Scm_Add2(Scm_Negate(SCM_2_31), SCM_MAKE_INT(1));
568 test_scm_c_scm("ScmInt64 roundtrip -2^31+1", vv,
569 Scm_MakeInteger64(Scm_GetInteger64(vv)));
570 vv = Scm_Negate(SCM_2_31);
571 test_scm_c_scm("ScmInt64 roundtrip -2^31", vv,
572 Scm_MakeInteger64(Scm_GetInteger64(vv)));
573 vv = Scm_Add2(Scm_Negate(SCM_2_32), SCM_MAKE_INT(1));
574 test_scm_c_scm("ScmInt64 roundtrip -2^32+1", vv,
575 Scm_MakeInteger64(Scm_GetInteger64(vv)));
576 vv = Scm_Negate(SCM_2_32);
577 test_scm_c_scm("ScmInt64 roundtrip -2^32", vv,
578 Scm_MakeInteger64(Scm_GetInteger64(vv)));
579
580
581 vv = Scm_Add2(SCM_2_63, SCM_MAKE_INT(-1));
582 test_scm_c_scm("ScmInt64 roundtrip 2^63-1", vv,
583 Scm_MakeInteger64(Scm_GetInteger64(vv)));
584 vv = Scm_Add2(SCM_2_63, SCM_MAKE_INT(-3));
585 test_scm_c_scm("ScmInt64 roundtrip 2^63-3", vv,
586 Scm_MakeInteger64(Scm_GetInteger64(vv)));
587 vv = Scm_Negate(SCM_2_63);
588 test_scm_c_scm("ScmInt64 roundtrip -2^63", vv,
589 Scm_MakeInteger64(Scm_GetInteger64(vv)));
590 vv = Scm_Add2(Scm_Negate(SCM_2_63), SCM_MAKE_INT(2));
591 test_scm_c_scm("ScmInt64 roundtrip -2^63+2", vv,
592 Scm_MakeInteger64(Scm_GetInteger64(vv)));
593
594 vv = Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1));
595 test_scm_c_scm("ScmUInt64 roundtrip 2^31", vv,
596 Scm_MakeIntegerU64(Scm_GetIntegerU64(vv)));
597 vv = SCM_2_31;
598 test_scm_c_scm("ScmUInt64 roundtrip 2^31", vv,
599 Scm_MakeIntegerU64(Scm_GetIntegerU64(vv)));
600 vv = Scm_Add2(SCM_2_32, SCM_MAKE_INT(-1));
601 test_scm_c_scm("ScmUInt64 roundtrip 2^32-1", vv,
602 Scm_MakeIntegerU64(Scm_GetIntegerU64(vv)));
603 vv = SCM_2_32;
604 test_scm_c_scm("ScmUInt64 roundtrip 2^32", vv,
605 Scm_MakeIntegerU64(Scm_GetIntegerU64(vv)));
606
607 vv = Scm_Add2(SCM_2_64, SCM_MAKE_INT(-1));
608 test_scm_c_scm("ScmUInt64 roundtrip 2^64-1", vv,
609 Scm_MakeIntegerU64(Scm_GetIntegerU64(vv)));
610
611 TEST_SECTION("integer conversions, clamping");
612 vv = SCM_2_32;
613 test_scm_c_scm("ScmInt32 clamp 2^32",
614 Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1)),
615 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
616 vv = SCM_2_63;
617 test_scm_c_scm("ScmInt32 clamp 2^63",
618 Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1)),
619 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
620 vv = SCM_2_64;
621 test_scm_c_scm("ScmInt32 clamp 2^64",
622 Scm_Add2(SCM_2_31, SCM_MAKE_INT(-1)),
623 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
624 vv = Scm_Negate(SCM_2_32);
625 test_scm_c_scm("ScmInt32 clamp -2^32",
626 Scm_Negate(SCM_2_31),
627 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
628 vv = Scm_Negate(SCM_2_63);
629 test_scm_c_scm("ScmInt32 clamp -2^63",
630 Scm_Negate(SCM_2_31),
631 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
632 vv = Scm_Negate(SCM_2_64);
633 test_scm_c_scm("ScmInt32 clamp -2^64",
634 Scm_Negate(SCM_2_31),
635 Scm_MakeInteger(Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL)));
636
637
638 TEST_SECTION("integer conversions, CLAMP_NONE");
639
640 vv = SCM_MAKE_INT(-1);
641 Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_NONE, &oor);
642 test_true("ScmUInt64 oor -1", oor);
643
644 vv = Scm_Add2(Scm_Negate(SCM_2_31), SCM_MAKE_INT(1));
645 Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_NONE, &oor);
646 test_true("ScmUInt64 oor -2^31+1", oor);
647
648 vv = Scm_Add2(Scm_Negate(SCM_2_32), SCM_MAKE_INT(1));
649 Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_NONE, &oor);
650 test_true("ScmUInt64 oor -2^32+1", oor);
651 }
652
653
654 /*=============================================================
655 * main
656 */
657 int main(int argc, char **argv)
658 {
659 const char *testmsg = "Testing integer arithmetic macros ... ";
660
661 Scm_Init(GAUCHE_SIGNATURE);
662
663 fprintf(stderr, "%-65s", testmsg);
664 message(stdout, testmsg, '=');
665
666 test_uadd();
667 test_uaddov();
668 test_saddov();
669 test_usub();
670 test_usubov();
671 test_ssubov();
672 test_umul();
673 test_umulov();
674 test_smulov();
675
676 test_32_64();
677
678 if (errcount) {
679 fprintf(stderr, "failed.\n");
680 fprintf(stdout, "failed.\n");
681 } else {
682 fprintf(stderr, "passed.\n");
683 fprintf(stdout, "passed.\n");
684 }
685 return 0;
686 }
687