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
);
45 } int_single_value_tests
[] = {
46 { &int_test_hash
, "0" },
47 { &int_test_hash
, "1" },
48 { &int_test_hash
, "-1" },
49 { &int_test_hash
, "23" },
50 { &int_test_hash
, "-23" },
51 { &int_test_hash
, "107" },
52 { &int_test_hash
, "32768" },
53 { &int_test_hash
, "2147483647" },
54 { &int_test_hash
, "-2147483647" },
55 { &int_test_hash
, "2147483648" },
56 { &int_test_hash
, "-2147483648" },
59 static void int_test_single_value()
63 for (i
= 0; i
< ARRAY_SIZE(int_single_value_tests
); i
+= 1) {
67 isl_int_read(val
, int_single_value_tests
[i
].val
);
69 (*int_single_value_tests
[i
].fn
)(val
);
75 static void invoke_alternate_representations_2args(char *arg1
, char *arg2
,
76 void (*fn
)(isl_int
, isl_int
))
84 for (j
= 0; j
< 4; ++j
) {
85 isl_int_read(int1
, arg1
);
86 isl_int_read(int2
, arg2
);
89 isl_sioimath_promote(&int1
);
91 isl_sioimath_try_demote(&int1
);
94 isl_sioimath_promote(&int2
);
96 isl_sioimath_try_demote(&int2
);
105 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
106 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
109 isl_int int1
, int2
, int3
;
115 for (j
= 0; j
< 8; ++j
) {
116 isl_int_read(int1
, arg1
);
117 isl_int_read(int2
, arg2
);
118 isl_int_read(int3
, arg3
);
121 isl_sioimath_promote(&int1
);
123 isl_sioimath_try_demote(&int1
);
126 isl_sioimath_promote(&int2
);
128 isl_sioimath_try_demote(&int2
);
131 isl_sioimath_promote(&int3
);
133 isl_sioimath_try_demote(&int3
);
135 (*fn
)(int1
, int2
, int3
);
142 #else /* USE_SMALL_INT_OPT */
144 static void int_test_single_value()
148 static void invoke_alternate_representations_2args(char *arg1
, char *arg2
,
149 void (*fn
)(isl_int
, isl_int
))
156 isl_int_read(int1
, arg1
);
157 isl_int_read(int2
, arg2
);
165 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
166 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
168 isl_int int1
, int2
, int3
;
174 isl_int_read(int1
, arg1
);
175 isl_int_read(int2
, arg2
);
176 isl_int_read(int3
, arg3
);
178 (*fn
)(int1
, int2
, int3
);
184 #endif /* USE_SMALL_INT_OPT */
186 static void int_test_neg(isl_int expected
, isl_int arg
)
189 isl_int_init(result
);
191 isl_int_neg(result
, arg
);
192 assert(isl_int_eq(result
, expected
));
194 isl_int_neg(result
, expected
);
195 assert(isl_int_eq(result
, arg
));
197 isl_int_clear(result
);
200 static void int_test_abs(isl_int expected
, isl_int arg
)
203 isl_int_init(result
);
205 isl_int_abs(result
, arg
);
206 assert(isl_int_eq(result
, expected
));
208 isl_int_clear(result
);
212 void (*fn
)(isl_int
, isl_int
);
213 char *expected
, *arg
;
214 } int_unary_tests
[] = {
215 { &int_test_neg
, "0", "0" },
216 { &int_test_neg
, "-1", "1" },
217 { &int_test_neg
, "-2147483647", "2147483647" },
218 { &int_test_neg
, "-2147483648", "2147483648" },
219 { &int_test_neg
, "-9223372036854775807", "9223372036854775807" },
220 { &int_test_neg
, "-9223372036854775808", "9223372036854775808" },
222 { &int_test_abs
, "0", "0" },
223 { &int_test_abs
, "1", "1" },
224 { &int_test_abs
, "1", "-1" },
225 { &int_test_abs
, "2147483647", "2147483647" },
226 { &int_test_abs
, "2147483648", "-2147483648" },
227 { &int_test_abs
, "9223372036854775807", "9223372036854775807" },
228 { &int_test_abs
, "9223372036854775808", "-9223372036854775808" },
231 static void int_test_divexact(isl_int expected
, isl_int lhs
, isl_int rhs
)
234 unsigned long rhsulong
;
236 if (isl_int_sgn(rhs
) == 0)
239 isl_int_init(result
);
241 isl_int_divexact(result
, lhs
, rhs
);
242 assert(isl_int_eq(expected
, result
));
244 isl_int_tdiv_q(result
, lhs
, rhs
);
245 assert(isl_int_eq(expected
, result
));
247 isl_int_fdiv_q(result
, lhs
, rhs
);
248 assert(isl_int_eq(expected
, result
));
250 isl_int_cdiv_q(result
, lhs
, rhs
);
251 assert(isl_int_eq(expected
, result
));
253 if (isl_int_fits_ulong(rhs
)) {
254 rhsulong
= isl_int_get_ui(rhs
);
256 isl_int_divexact_ui(result
, lhs
, rhsulong
);
257 assert(isl_int_eq(expected
, result
));
259 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
260 assert(isl_int_eq(expected
, result
));
263 isl_int_clear(result
);
266 static void int_test_mul(isl_int expected
, isl_int lhs
, isl_int rhs
)
269 isl_int_init(result
);
271 isl_int_mul(result
, lhs
, rhs
);
272 assert(isl_int_eq(expected
, result
));
274 if (isl_int_fits_ulong(rhs
)) {
275 unsigned long rhsulong
= isl_int_get_ui(rhs
);
277 isl_int_mul_ui(result
, lhs
, rhsulong
);
278 assert(isl_int_eq(expected
, result
));
281 if (isl_int_fits_slong(rhs
)) {
282 unsigned long rhsslong
= isl_int_get_si(rhs
);
284 isl_int_mul_si(result
, lhs
, rhsslong
);
285 assert(isl_int_eq(expected
, result
));
288 isl_int_clear(result
);
291 /* Use a triple that satisfies 'product = factor1 * factor2' to check the
292 * operations mul, divexact, tdiv, fdiv and cdiv.
294 static void int_test_product(isl_int product
, isl_int factor1
, isl_int factor2
)
296 int_test_divexact(factor1
, product
, factor2
);
297 int_test_divexact(factor2
, product
, factor1
);
299 int_test_mul(product
, factor1
, factor2
);
300 int_test_mul(product
, factor2
, factor1
);
303 static void int_test_add(isl_int expected
, isl_int lhs
, isl_int rhs
)
306 isl_int_init(result
);
308 isl_int_add(result
, lhs
, rhs
);
309 assert(isl_int_eq(expected
, result
));
311 isl_int_clear(result
);
314 static void int_test_sub(isl_int expected
, isl_int lhs
, isl_int rhs
)
317 isl_int_init(result
);
319 isl_int_sub(result
, lhs
, rhs
);
320 assert(isl_int_eq(expected
, result
));
322 isl_int_clear(result
);
325 /* Use a triple that satisfies 'sum = term1 + term2' to check the operations add
328 static void int_test_sum(isl_int sum
, isl_int term1
, isl_int term2
)
330 int_test_sub(term1
, sum
, term2
);
331 int_test_sub(term2
, sum
, term1
);
333 int_test_add(sum
, term1
, term2
);
334 int_test_add(sum
, term2
, term1
);
337 static void int_test_fdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
339 unsigned long rhsulong
;
341 isl_int_init(result
);
343 isl_int_fdiv_q(result
, lhs
, rhs
);
344 assert(isl_int_eq(expected
, result
));
346 if (isl_int_fits_ulong(rhs
)) {
347 rhsulong
= isl_int_get_ui(rhs
);
349 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
350 assert(isl_int_eq(expected
, result
));
353 isl_int_clear(result
);
356 static void int_test_cdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
359 isl_int_init(result
);
361 isl_int_cdiv_q(result
, lhs
, rhs
);
362 assert(isl_int_eq(expected
, result
));
364 isl_int_clear(result
);
367 static void int_test_tdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
370 isl_int_init(result
);
372 isl_int_tdiv_q(result
, lhs
, rhs
);
373 assert(isl_int_eq(expected
, result
));
375 isl_int_clear(result
);
378 static void int_test_fdiv_r(isl_int expected
, isl_int lhs
, isl_int rhs
)
381 isl_int_init(result
);
383 isl_int_fdiv_r(result
, lhs
, rhs
);
384 assert(isl_int_eq(expected
, result
));
386 isl_int_clear(result
);
389 static void int_test_gcd(isl_int expected
, isl_int lhs
, isl_int rhs
)
392 isl_int_init(result
);
394 isl_int_gcd(result
, lhs
, rhs
);
395 assert(isl_int_eq(expected
, result
));
397 isl_int_gcd(result
, rhs
, lhs
);
398 assert(isl_int_eq(expected
, result
));
400 isl_int_clear(result
);
403 static void int_test_lcm(isl_int expected
, isl_int lhs
, isl_int rhs
)
406 isl_int_init(result
);
408 isl_int_lcm(result
, lhs
, rhs
);
409 assert(isl_int_eq(expected
, result
));
411 isl_int_lcm(result
, rhs
, lhs
);
412 assert(isl_int_eq(expected
, result
));
414 isl_int_clear(result
);
417 static int sgn(int val
)
426 static void int_test_cmp(int exp
, isl_int lhs
, isl_int rhs
)
430 assert(exp
== sgn(isl_int_cmp(lhs
, rhs
)));
432 if (isl_int_fits_slong(rhs
)) {
433 rhslong
= isl_int_get_si(rhs
);
434 assert(exp
== sgn(isl_int_cmp_si(lhs
, rhslong
)));
438 /* Test the comparison relations over two numbers.
439 * expected is the sign (1, 0 or -1) of 'lhs - rhs'.
441 static void int_test_cmps(isl_int expected
, isl_int lhs
, isl_int rhs
)
446 exp
= isl_int_get_si(expected
);
449 isl_int_sub(diff
, lhs
, rhs
);
450 assert(exp
== isl_int_sgn(diff
));
453 int_test_cmp(exp
, lhs
, rhs
);
454 int_test_cmp(-exp
, rhs
, lhs
);
457 static void int_test_abs_cmp(isl_int expected
, isl_int lhs
, isl_int rhs
)
461 exp
= isl_int_get_si(expected
);
462 assert(exp
== sgn(isl_int_abs_cmp(lhs
, rhs
)));
463 assert(-exp
== sgn(isl_int_abs_cmp(rhs
, lhs
)));
467 void (*fn
)(isl_int
, isl_int
, isl_int
);
468 char *expected
, *lhs
, *rhs
;
469 } int_binary_tests
[] = {
470 { &int_test_sum
, "0", "0", "0" },
471 { &int_test_sum
, "1", "1", "0" },
472 { &int_test_sum
, "2", "1", "1" },
473 { &int_test_sum
, "-1", "0", "-1" },
474 { &int_test_sum
, "-2", "-1", "-1" },
476 { &int_test_sum
, "2147483647", "1073741823", "1073741824" },
477 { &int_test_sum
, "-2147483648", "-1073741824", "-1073741824" },
479 { &int_test_sum
, "2147483648", "2147483647", "1" },
480 { &int_test_sum
, "-2147483648", "-2147483647", "-1" },
482 { &int_test_product
, "0", "0", "0" },
483 { &int_test_product
, "0", "0", "1" },
484 { &int_test_product
, "1", "1", "1" },
486 { &int_test_product
, "6", "2", "3" },
487 { &int_test_product
, "-6", "2", "-3" },
488 { &int_test_product
, "-6", "-2", "3" },
489 { &int_test_product
, "6", "-2", "-3" },
491 { &int_test_product
, "2147483648", "65536", "32768" },
492 { &int_test_product
, "-2147483648", "65536", "-32768" },
495 "4611686014132420609", "2147483647", "2147483647" },
497 "-4611686014132420609", "-2147483647", "2147483647" },
500 "4611686016279904256", "2147483647", "2147483648" },
502 "-4611686016279904256", "-2147483647", "2147483648" },
504 "-4611686016279904256", "2147483647", "-2147483648" },
506 "4611686016279904256", "-2147483647", "-2147483648" },
508 { &int_test_product
, "85070591730234615847396907784232501249",
509 "9223372036854775807", "9223372036854775807" },
510 { &int_test_product
, "-85070591730234615847396907784232501249",
511 "-9223372036854775807", "9223372036854775807" },
513 { &int_test_product
, "85070591730234615856620279821087277056",
514 "9223372036854775807", "9223372036854775808" },
515 { &int_test_product
, "-85070591730234615856620279821087277056",
516 "-9223372036854775807", "9223372036854775808" },
517 { &int_test_product
, "-85070591730234615856620279821087277056",
518 "9223372036854775807", "-9223372036854775808" },
519 { &int_test_product
, "85070591730234615856620279821087277056",
520 "-9223372036854775807", "-9223372036854775808" },
522 { &int_test_product
, "340282366920938463426481119284349108225",
523 "18446744073709551615", "18446744073709551615" },
524 { &int_test_product
, "-340282366920938463426481119284349108225",
525 "-18446744073709551615", "18446744073709551615" },
527 { &int_test_product
, "340282366920938463444927863358058659840",
528 "18446744073709551615", "18446744073709551616" },
529 { &int_test_product
, "-340282366920938463444927863358058659840",
530 "-18446744073709551615", "18446744073709551616" },
531 { &int_test_product
, "-340282366920938463444927863358058659840",
532 "18446744073709551615", "-18446744073709551616" },
533 { &int_test_product
, "340282366920938463444927863358058659840",
534 "-18446744073709551615", "-18446744073709551616" },
536 { &int_test_fdiv
, "0", "1", "2" },
537 { &int_test_fdiv_r
, "1", "1", "3" },
538 { &int_test_fdiv
, "-1", "-1", "2" },
539 { &int_test_fdiv_r
, "2", "-1", "3" },
540 { &int_test_fdiv
, "-1", "1", "-2" },
541 { &int_test_fdiv_r
, "-2", "1", "-3" },
542 { &int_test_fdiv
, "0", "-1", "-2" },
543 { &int_test_fdiv_r
, "-1", "-1", "-3" },
545 { &int_test_cdiv
, "1", "1", "2" },
546 { &int_test_cdiv
, "0", "-1", "2" },
547 { &int_test_cdiv
, "0", "1", "-2" },
548 { &int_test_cdiv
, "1", "-1", "-2" },
550 { &int_test_tdiv
, "0", "1", "2" },
551 { &int_test_tdiv
, "0", "-1", "2" },
552 { &int_test_tdiv
, "0", "1", "-2" },
553 { &int_test_tdiv
, "0", "-1", "-2" },
555 { &int_test_gcd
, "0", "0", "0" },
556 { &int_test_lcm
, "0", "0", "0" },
557 { &int_test_gcd
, "7", "0", "7" },
558 { &int_test_lcm
, "0", "0", "7" },
559 { &int_test_gcd
, "1", "1", "1" },
560 { &int_test_lcm
, "1", "1", "1" },
561 { &int_test_gcd
, "1", "1", "-1" },
562 { &int_test_lcm
, "1", "1", "-1" },
563 { &int_test_gcd
, "1", "-1", "-1" },
564 { &int_test_lcm
, "1", "-1", "-1" },
565 { &int_test_gcd
, "3", "6", "9" },
566 { &int_test_lcm
, "18", "6", "9" },
567 { &int_test_gcd
, "1", "14", "2147483647" },
568 { &int_test_lcm
, "15032385529", "7", "2147483647" },
569 { &int_test_gcd
, "2", "6", "-2147483648" },
570 { &int_test_lcm
, "6442450944", "6", "-2147483648" },
571 { &int_test_gcd
, "1", "6", "9223372036854775807" },
572 { &int_test_lcm
, "55340232221128654842", "6", "9223372036854775807" },
573 { &int_test_gcd
, "2", "6", "-9223372036854775808" },
574 { &int_test_lcm
, "27670116110564327424", "6", "-9223372036854775808" },
575 { &int_test_gcd
, "1", "18446744073709551616", "18446744073709551615" },
576 { &int_test_lcm
, "340282366920938463444927863358058659840",
577 "18446744073709551616", "18446744073709551615" },
579 { &int_test_cmps
, "0", "0", "0" },
580 { &int_test_abs_cmp
, "0", "0", "0" },
581 { &int_test_cmps
, "1", "1", "0" },
582 { &int_test_abs_cmp
, "1", "1", "0" },
583 { &int_test_cmps
, "-1", "-1", "0" },
584 { &int_test_abs_cmp
, "1", "-1", "0" },
585 { &int_test_cmps
, "-1", "-1", "1" },
586 { &int_test_abs_cmp
, "0", "-1", "1" },
588 { &int_test_cmps
, "-1", "5", "2147483647" },
589 { &int_test_abs_cmp
, "-1", "5", "2147483647" },
590 { &int_test_cmps
, "1", "5", "-2147483648" },
591 { &int_test_abs_cmp
, "-1", "5", "-2147483648" },
592 { &int_test_cmps
, "-1", "5", "9223372036854775807" },
593 { &int_test_abs_cmp
, "-1", "5", "9223372036854775807" },
594 { &int_test_cmps
, "1", "5", "-9223372036854775809" },
595 { &int_test_abs_cmp
, "-1", "5", "-9223372036854775809" },
598 /* Tests the isl_int_* function to give the expected results. Tests are
599 * grouped by the number of arguments they take.
601 * If small integer optimization is enabled, we also test whether the results
602 * are the same in small and big representation.
608 int_test_single_value();
610 for (i
= 0; i
< ARRAY_SIZE(int_unary_tests
); i
+= 1) {
611 invoke_alternate_representations_2args(
612 int_unary_tests
[i
].expected
, int_unary_tests
[i
].arg
,
613 int_unary_tests
[i
].fn
);
616 for (i
= 0; i
< ARRAY_SIZE(int_binary_tests
); i
+= 1) {
617 invoke_alternate_representations_3args(
618 int_binary_tests
[i
].expected
, int_binary_tests
[i
].lhs
,
619 int_binary_tests
[i
].rhs
, int_binary_tests
[i
].fn
);