2 * Copyright 2015 INRIA Paris-Rocquencourt
4 * Use of this software is governed by the MIT license
6 * Written by Michael Kruse, INRIA Paris-Rocquencourt,
7 * Domaine de Voluceau, Rocquenqourt, B.P. 105,
8 * 78153 Le Chesnay Cedex France
15 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
17 #ifdef USE_SMALL_INT_OPT
18 /* Test whether small and big representation of the same number have the same
21 static void int_test_hash(isl_int val
)
23 uint32_t demotedhash
, promotedhash
;
24 isl_int demoted
, promoted
;
26 isl_int_init(demoted
);
27 isl_int_set(demoted
, val
);
29 isl_int_init(promoted
);
30 isl_int_set(promoted
, val
);
32 isl_sioimath_try_demote(demoted
);
33 isl_sioimath_promote(promoted
);
35 assert(isl_int_eq(demoted
, promoted
));
37 demotedhash
= isl_int_hash(demoted
, 0);
38 promotedhash
= isl_int_hash(promoted
, 0);
39 assert(demotedhash
== promotedhash
);
41 isl_int_clear(demoted
);
42 isl_int_clear(promoted
);
48 } int_single_value_tests
[] = {
49 { &int_test_hash
, "0" },
50 { &int_test_hash
, "1" },
51 { &int_test_hash
, "-1" },
52 { &int_test_hash
, "23" },
53 { &int_test_hash
, "-23" },
54 { &int_test_hash
, "107" },
55 { &int_test_hash
, "32768" },
56 { &int_test_hash
, "2147483647" },
57 { &int_test_hash
, "-2147483647" },
58 { &int_test_hash
, "2147483648" },
59 { &int_test_hash
, "-2147483648" },
62 static void int_test_single_value()
66 for (i
= 0; i
< ARRAY_SIZE(int_single_value_tests
); i
+= 1) {
70 isl_int_read(val
, int_single_value_tests
[i
].val
);
72 (*int_single_value_tests
[i
].fn
)(val
);
78 static void invoke_alternate_representations_2args(char *arg1
, char *arg2
,
79 void (*fn
)(isl_int
, isl_int
))
87 for (j
= 0; j
< 4; ++j
) {
88 isl_int_read(int1
, arg1
);
89 isl_int_read(int2
, arg2
);
92 isl_sioimath_promote(int1
);
94 isl_sioimath_try_demote(int1
);
97 isl_sioimath_promote(int2
);
99 isl_sioimath_try_demote(int2
);
108 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
109 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
112 isl_int int1
, int2
, int3
;
118 for (j
= 0; j
< 8; ++j
) {
119 isl_int_read(int1
, arg1
);
120 isl_int_read(int2
, arg2
);
121 isl_int_read(int3
, arg3
);
124 isl_sioimath_promote(int1
);
126 isl_sioimath_try_demote(int1
);
129 isl_sioimath_promote(int2
);
131 isl_sioimath_try_demote(int2
);
134 isl_sioimath_promote(int3
);
136 isl_sioimath_try_demote(int3
);
138 (*fn
)(int1
, int2
, int3
);
145 #else /* USE_SMALL_INT_OPT */
147 static void int_test_single_value()
151 static void invoke_alternate_representations_2args(char *arg1
, char *arg2
,
152 void (*fn
)(isl_int
, isl_int
))
159 isl_int_read(int1
, arg1
);
160 isl_int_read(int2
, arg2
);
168 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
169 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
171 isl_int int1
, int2
, int3
;
177 isl_int_read(int1
, arg1
);
178 isl_int_read(int2
, arg2
);
179 isl_int_read(int3
, arg3
);
181 (*fn
)(int1
, int2
, int3
);
187 #endif /* USE_SMALL_INT_OPT */
189 static void int_test_neg(isl_int expected
, isl_int arg
)
192 isl_int_init(result
);
194 isl_int_neg(result
, arg
);
195 assert(isl_int_eq(result
, expected
));
197 isl_int_neg(result
, expected
);
198 assert(isl_int_eq(result
, arg
));
200 isl_int_clear(result
);
203 static void int_test_abs(isl_int expected
, isl_int arg
)
206 isl_int_init(result
);
208 isl_int_abs(result
, arg
);
209 assert(isl_int_eq(result
, expected
));
211 isl_int_clear(result
);
215 void (*fn
)(isl_int
, isl_int
);
216 char *expected
, *arg
;
217 } int_unary_tests
[] = {
218 { &int_test_neg
, "0", "0" },
219 { &int_test_neg
, "-1", "1" },
220 { &int_test_neg
, "-2147483647", "2147483647" },
221 { &int_test_neg
, "-2147483648", "2147483648" },
222 { &int_test_neg
, "-9223372036854775807", "9223372036854775807" },
223 { &int_test_neg
, "-9223372036854775808", "9223372036854775808" },
225 { &int_test_abs
, "0", "0" },
226 { &int_test_abs
, "1", "1" },
227 { &int_test_abs
, "1", "-1" },
228 { &int_test_abs
, "2147483647", "2147483647" },
229 { &int_test_abs
, "2147483648", "-2147483648" },
230 { &int_test_abs
, "9223372036854775807", "9223372036854775807" },
231 { &int_test_abs
, "9223372036854775808", "-9223372036854775808" },
234 static void int_test_divexact(isl_int expected
, isl_int lhs
, isl_int rhs
)
237 unsigned long rhsulong
;
239 if (isl_int_sgn(rhs
) == 0)
242 isl_int_init(result
);
244 isl_int_divexact(result
, lhs
, rhs
);
245 assert(isl_int_eq(expected
, result
));
247 isl_int_tdiv_q(result
, lhs
, rhs
);
248 assert(isl_int_eq(expected
, result
));
250 isl_int_fdiv_q(result
, lhs
, rhs
);
251 assert(isl_int_eq(expected
, result
));
253 isl_int_cdiv_q(result
, lhs
, rhs
);
254 assert(isl_int_eq(expected
, result
));
256 if (isl_int_fits_ulong(rhs
)) {
257 rhsulong
= isl_int_get_ui(rhs
);
259 isl_int_divexact_ui(result
, lhs
, rhsulong
);
260 assert(isl_int_eq(expected
, result
));
262 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
263 assert(isl_int_eq(expected
, result
));
266 isl_int_clear(result
);
269 static void int_test_mul(isl_int expected
, isl_int lhs
, isl_int rhs
)
272 isl_int_init(result
);
274 isl_int_mul(result
, lhs
, rhs
);
275 assert(isl_int_eq(expected
, result
));
277 if (isl_int_fits_ulong(rhs
)) {
278 unsigned long rhsulong
= isl_int_get_ui(rhs
);
280 isl_int_mul_ui(result
, lhs
, rhsulong
);
281 assert(isl_int_eq(expected
, result
));
284 if (isl_int_fits_slong(rhs
)) {
285 unsigned long rhsslong
= isl_int_get_si(rhs
);
287 isl_int_mul_si(result
, lhs
, rhsslong
);
288 assert(isl_int_eq(expected
, result
));
291 isl_int_clear(result
);
294 /* Use a triple that satisfies 'product = factor1 * factor2' to check the
295 * operations mul, divexact, tdiv, fdiv and cdiv.
297 static void int_test_product(isl_int product
, isl_int factor1
, isl_int factor2
)
299 int_test_divexact(factor1
, product
, factor2
);
300 int_test_divexact(factor2
, product
, factor1
);
302 int_test_mul(product
, factor1
, factor2
);
303 int_test_mul(product
, factor2
, factor1
);
306 static void int_test_add(isl_int expected
, isl_int lhs
, isl_int rhs
)
309 isl_int_init(result
);
311 isl_int_add(result
, lhs
, rhs
);
312 assert(isl_int_eq(expected
, result
));
314 isl_int_clear(result
);
317 static void int_test_sub(isl_int expected
, isl_int lhs
, isl_int rhs
)
320 isl_int_init(result
);
322 isl_int_sub(result
, lhs
, rhs
);
323 assert(isl_int_eq(expected
, result
));
325 isl_int_clear(result
);
328 /* Use a triple that satisfies 'sum = term1 + term2' to check the operations add
331 static void int_test_sum(isl_int sum
, isl_int term1
, isl_int term2
)
333 int_test_sub(term1
, sum
, term2
);
334 int_test_sub(term2
, sum
, term1
);
336 int_test_add(sum
, term1
, term2
);
337 int_test_add(sum
, term2
, term1
);
340 static void int_test_fdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
342 unsigned long rhsulong
;
344 isl_int_init(result
);
346 isl_int_fdiv_q(result
, lhs
, rhs
);
347 assert(isl_int_eq(expected
, result
));
349 if (isl_int_fits_ulong(rhs
)) {
350 rhsulong
= isl_int_get_ui(rhs
);
352 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
353 assert(isl_int_eq(expected
, result
));
356 isl_int_clear(result
);
359 static void int_test_cdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
362 isl_int_init(result
);
364 isl_int_cdiv_q(result
, lhs
, rhs
);
365 assert(isl_int_eq(expected
, result
));
367 isl_int_clear(result
);
370 static void int_test_tdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
373 isl_int_init(result
);
375 isl_int_tdiv_q(result
, lhs
, rhs
);
376 assert(isl_int_eq(expected
, result
));
378 isl_int_clear(result
);
381 static void int_test_fdiv_r(isl_int expected
, isl_int lhs
, isl_int rhs
)
384 isl_int_init(result
);
386 isl_int_fdiv_r(result
, lhs
, rhs
);
387 assert(isl_int_eq(expected
, result
));
389 isl_int_clear(result
);
392 static void int_test_gcd(isl_int expected
, isl_int lhs
, isl_int rhs
)
395 isl_int_init(result
);
397 isl_int_gcd(result
, lhs
, rhs
);
398 assert(isl_int_eq(expected
, result
));
400 isl_int_gcd(result
, rhs
, lhs
);
401 assert(isl_int_eq(expected
, result
));
403 isl_int_clear(result
);
406 static void int_test_lcm(isl_int expected
, isl_int lhs
, isl_int rhs
)
409 isl_int_init(result
);
411 isl_int_lcm(result
, lhs
, rhs
);
412 assert(isl_int_eq(expected
, result
));
414 isl_int_lcm(result
, rhs
, lhs
);
415 assert(isl_int_eq(expected
, result
));
417 isl_int_clear(result
);
420 static int sgn(int val
)
429 static void int_test_cmp(int exp
, isl_int lhs
, isl_int rhs
)
433 assert(exp
== sgn(isl_int_cmp(lhs
, rhs
)));
435 if (isl_int_fits_slong(rhs
)) {
436 rhslong
= isl_int_get_si(rhs
);
437 assert(exp
== sgn(isl_int_cmp_si(lhs
, rhslong
)));
441 /* Test the comparison relations over two numbers.
442 * expected is the sign (1, 0 or -1) of 'lhs - rhs'.
444 static void int_test_cmps(isl_int expected
, isl_int lhs
, isl_int rhs
)
449 exp
= isl_int_get_si(expected
);
452 isl_int_sub(diff
, lhs
, rhs
);
453 assert(exp
== isl_int_sgn(diff
));
456 int_test_cmp(exp
, lhs
, rhs
);
457 int_test_cmp(-exp
, rhs
, lhs
);
460 static void int_test_abs_cmp(isl_int expected
, isl_int lhs
, isl_int rhs
)
464 exp
= isl_int_get_si(expected
);
465 assert(exp
== sgn(isl_int_abs_cmp(lhs
, rhs
)));
466 assert(-exp
== sgn(isl_int_abs_cmp(rhs
, lhs
)));
470 void (*fn
)(isl_int
, isl_int
, isl_int
);
471 char *expected
, *lhs
, *rhs
;
472 } int_binary_tests
[] = {
473 { &int_test_sum
, "0", "0", "0" },
474 { &int_test_sum
, "1", "1", "0" },
475 { &int_test_sum
, "2", "1", "1" },
476 { &int_test_sum
, "-1", "0", "-1" },
477 { &int_test_sum
, "-2", "-1", "-1" },
479 { &int_test_sum
, "2147483647", "1073741823", "1073741824" },
480 { &int_test_sum
, "-2147483648", "-1073741824", "-1073741824" },
482 { &int_test_sum
, "2147483648", "2147483647", "1" },
483 { &int_test_sum
, "-2147483648", "-2147483647", "-1" },
485 { &int_test_product
, "0", "0", "0" },
486 { &int_test_product
, "0", "0", "1" },
487 { &int_test_product
, "1", "1", "1" },
489 { &int_test_product
, "6", "2", "3" },
490 { &int_test_product
, "-6", "2", "-3" },
491 { &int_test_product
, "-6", "-2", "3" },
492 { &int_test_product
, "6", "-2", "-3" },
494 { &int_test_product
, "2147483648", "65536", "32768" },
495 { &int_test_product
, "-2147483648", "65536", "-32768" },
498 "4611686014132420609", "2147483647", "2147483647" },
500 "-4611686014132420609", "-2147483647", "2147483647" },
503 "4611686016279904256", "2147483647", "2147483648" },
505 "-4611686016279904256", "-2147483647", "2147483648" },
507 "-4611686016279904256", "2147483647", "-2147483648" },
509 "4611686016279904256", "-2147483647", "-2147483648" },
511 { &int_test_product
, "85070591730234615847396907784232501249",
512 "9223372036854775807", "9223372036854775807" },
513 { &int_test_product
, "-85070591730234615847396907784232501249",
514 "-9223372036854775807", "9223372036854775807" },
516 { &int_test_product
, "85070591730234615856620279821087277056",
517 "9223372036854775807", "9223372036854775808" },
518 { &int_test_product
, "-85070591730234615856620279821087277056",
519 "-9223372036854775807", "9223372036854775808" },
520 { &int_test_product
, "-85070591730234615856620279821087277056",
521 "9223372036854775807", "-9223372036854775808" },
522 { &int_test_product
, "85070591730234615856620279821087277056",
523 "-9223372036854775807", "-9223372036854775808" },
525 { &int_test_product
, "340282366920938463426481119284349108225",
526 "18446744073709551615", "18446744073709551615" },
527 { &int_test_product
, "-340282366920938463426481119284349108225",
528 "-18446744073709551615", "18446744073709551615" },
530 { &int_test_product
, "340282366920938463444927863358058659840",
531 "18446744073709551615", "18446744073709551616" },
532 { &int_test_product
, "-340282366920938463444927863358058659840",
533 "-18446744073709551615", "18446744073709551616" },
534 { &int_test_product
, "-340282366920938463444927863358058659840",
535 "18446744073709551615", "-18446744073709551616" },
536 { &int_test_product
, "340282366920938463444927863358058659840",
537 "-18446744073709551615", "-18446744073709551616" },
539 { &int_test_fdiv
, "0", "1", "2" },
540 { &int_test_fdiv_r
, "1", "1", "3" },
541 { &int_test_fdiv
, "-1", "-1", "2" },
542 { &int_test_fdiv_r
, "2", "-1", "3" },
543 { &int_test_fdiv
, "-1", "1", "-2" },
544 { &int_test_fdiv_r
, "-2", "1", "-3" },
545 { &int_test_fdiv
, "0", "-1", "-2" },
546 { &int_test_fdiv_r
, "-1", "-1", "-3" },
548 { &int_test_cdiv
, "1", "1", "2" },
549 { &int_test_cdiv
, "0", "-1", "2" },
550 { &int_test_cdiv
, "0", "1", "-2" },
551 { &int_test_cdiv
, "1", "-1", "-2" },
553 { &int_test_tdiv
, "0", "1", "2" },
554 { &int_test_tdiv
, "0", "-1", "2" },
555 { &int_test_tdiv
, "0", "1", "-2" },
556 { &int_test_tdiv
, "0", "-1", "-2" },
558 { &int_test_gcd
, "0", "0", "0" },
559 { &int_test_lcm
, "0", "0", "0" },
560 { &int_test_gcd
, "7", "0", "7" },
561 { &int_test_lcm
, "0", "0", "7" },
562 { &int_test_gcd
, "1", "1", "1" },
563 { &int_test_lcm
, "1", "1", "1" },
564 { &int_test_gcd
, "1", "1", "-1" },
565 { &int_test_lcm
, "1", "1", "-1" },
566 { &int_test_gcd
, "1", "-1", "-1" },
567 { &int_test_lcm
, "1", "-1", "-1" },
568 { &int_test_gcd
, "3", "6", "9" },
569 { &int_test_lcm
, "18", "6", "9" },
570 { &int_test_gcd
, "1", "14", "2147483647" },
571 { &int_test_lcm
, "15032385529", "7", "2147483647" },
572 { &int_test_gcd
, "2", "6", "-2147483648" },
573 { &int_test_lcm
, "6442450944", "6", "-2147483648" },
574 { &int_test_gcd
, "1", "6", "9223372036854775807" },
575 { &int_test_lcm
, "55340232221128654842", "6", "9223372036854775807" },
576 { &int_test_gcd
, "2", "6", "-9223372036854775808" },
577 { &int_test_lcm
, "27670116110564327424", "6", "-9223372036854775808" },
578 { &int_test_gcd
, "1", "18446744073709551616", "18446744073709551615" },
579 { &int_test_lcm
, "340282366920938463444927863358058659840",
580 "18446744073709551616", "18446744073709551615" },
582 { &int_test_cmps
, "0", "0", "0" },
583 { &int_test_abs_cmp
, "0", "0", "0" },
584 { &int_test_cmps
, "1", "1", "0" },
585 { &int_test_abs_cmp
, "1", "1", "0" },
586 { &int_test_cmps
, "-1", "-1", "0" },
587 { &int_test_abs_cmp
, "1", "-1", "0" },
588 { &int_test_cmps
, "-1", "-1", "1" },
589 { &int_test_abs_cmp
, "0", "-1", "1" },
591 { &int_test_cmps
, "-1", "5", "2147483647" },
592 { &int_test_abs_cmp
, "-1", "5", "2147483647" },
593 { &int_test_cmps
, "1", "5", "-2147483648" },
594 { &int_test_abs_cmp
, "-1", "5", "-2147483648" },
595 { &int_test_cmps
, "-1", "5", "9223372036854775807" },
596 { &int_test_abs_cmp
, "-1", "5", "9223372036854775807" },
597 { &int_test_cmps
, "1", "5", "-9223372036854775809" },
598 { &int_test_abs_cmp
, "-1", "5", "-9223372036854775809" },
601 /* Tests the isl_int_* function to give the expected results. Tests are
602 * grouped by the number of arguments they take.
604 * If small integer optimization is enabled, we also test whether the results
605 * are the same in small and big representation.
611 int_test_single_value();
613 for (i
= 0; i
< ARRAY_SIZE(int_unary_tests
); i
+= 1) {
614 invoke_alternate_representations_2args(
615 int_unary_tests
[i
].expected
, int_unary_tests
[i
].arg
,
616 int_unary_tests
[i
].fn
);
619 for (i
= 0; i
< ARRAY_SIZE(int_binary_tests
); i
+= 1) {
620 invoke_alternate_representations_3args(
621 int_binary_tests
[i
].expected
, int_binary_tests
[i
].lhs
,
622 int_binary_tests
[i
].rhs
, int_binary_tests
[i
].fn
);