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
))
83 for (int j
= 0; j
< 4; ++j
) {
84 isl_int_read(int1
, arg1
);
85 isl_int_read(int2
, arg2
);
88 isl_sioimath_promote(&int1
);
90 isl_sioimath_try_demote(&int1
);
93 isl_sioimath_promote(&int2
);
95 isl_sioimath_try_demote(&int2
);
104 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
105 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
107 isl_int int1
, int2
, int3
;
113 for (int j
= 0; j
< 8; ++j
) {
114 isl_int_read(int1
, arg1
);
115 isl_int_read(int2
, arg2
);
116 isl_int_read(int3
, arg3
);
119 isl_sioimath_promote(&int1
);
121 isl_sioimath_try_demote(&int1
);
124 isl_sioimath_promote(&int2
);
126 isl_sioimath_try_demote(&int2
);
129 isl_sioimath_promote(&int3
);
131 isl_sioimath_try_demote(&int3
);
133 (*fn
)(int1
, int2
, int3
);
140 #else /* USE_SMALL_INT_OPT */
142 static void int_test_single_value()
146 static void invoke_alternate_representations_2args(char *arg1
, char *arg2
,
147 void (*fn
)(isl_int
, isl_int
))
154 isl_int_read(int1
, arg1
);
155 isl_int_read(int2
, arg2
);
163 static void invoke_alternate_representations_3args(char *arg1
, char *arg2
,
164 char *arg3
, void (*fn
)(isl_int
, isl_int
, isl_int
))
166 isl_int int1
, int2
, int3
;
172 isl_int_read(int1
, arg1
);
173 isl_int_read(int2
, arg2
);
174 isl_int_read(int3
, arg3
);
176 (*fn
)(int1
, int2
, int3
);
182 #endif /* USE_SMALL_INT_OPT */
184 static void int_test_neg(isl_int expected
, isl_int arg
)
187 isl_int_init(result
);
189 isl_int_neg(result
, arg
);
190 assert(isl_int_eq(result
, expected
));
192 isl_int_neg(result
, expected
);
193 assert(isl_int_eq(result
, arg
));
195 isl_int_clear(result
);
198 static void int_test_abs(isl_int expected
, isl_int arg
)
201 isl_int_init(result
);
203 isl_int_abs(result
, arg
);
204 assert(isl_int_eq(result
, expected
));
206 isl_int_clear(result
);
210 void (*fn
)(isl_int
, isl_int
);
211 char *expected
, *arg
;
212 } int_unary_tests
[] = {
213 { &int_test_neg
, "0", "0" },
214 { &int_test_neg
, "-1", "1" },
215 { &int_test_neg
, "-2147483647", "2147483647" },
216 { &int_test_neg
, "-2147483648", "2147483648" },
217 { &int_test_neg
, "-9223372036854775807", "9223372036854775807" },
218 { &int_test_neg
, "-9223372036854775808", "9223372036854775808" },
220 { &int_test_abs
, "0", "0" },
221 { &int_test_abs
, "1", "1" },
222 { &int_test_abs
, "1", "-1" },
223 { &int_test_abs
, "2147483647", "2147483647" },
224 { &int_test_abs
, "2147483648", "-2147483648" },
225 { &int_test_abs
, "9223372036854775807", "9223372036854775807" },
226 { &int_test_abs
, "9223372036854775808", "-9223372036854775808" },
229 static void int_test_divexact(isl_int expected
, isl_int lhs
, isl_int rhs
)
232 unsigned long rhsulong
;
234 if (isl_int_sgn(rhs
) == 0)
237 isl_int_init(result
);
239 isl_int_divexact(result
, lhs
, rhs
);
240 assert(isl_int_eq(expected
, result
));
242 isl_int_tdiv_q(result
, lhs
, rhs
);
243 assert(isl_int_eq(expected
, result
));
245 isl_int_fdiv_q(result
, lhs
, rhs
);
246 assert(isl_int_eq(expected
, result
));
248 isl_int_cdiv_q(result
, lhs
, rhs
);
249 assert(isl_int_eq(expected
, result
));
251 if (isl_int_fits_ulong(rhs
)) {
252 rhsulong
= isl_int_get_ui(rhs
);
254 isl_int_divexact_ui(result
, lhs
, rhsulong
);
255 assert(isl_int_eq(expected
, result
));
257 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
258 assert(isl_int_eq(expected
, result
));
261 isl_int_clear(result
);
264 static void int_test_mul(isl_int expected
, isl_int lhs
, isl_int rhs
)
267 isl_int_init(result
);
269 isl_int_mul(result
, lhs
, rhs
);
270 assert(isl_int_eq(expected
, result
));
272 if (isl_int_fits_ulong(rhs
)) {
273 unsigned long rhsulong
= isl_int_get_ui(rhs
);
275 isl_int_mul_ui(result
, lhs
, rhsulong
);
276 assert(isl_int_eq(expected
, result
));
279 if (isl_int_fits_slong(rhs
)) {
280 unsigned long rhsslong
= isl_int_get_si(rhs
);
282 isl_int_mul_si(result
, lhs
, rhsslong
);
283 assert(isl_int_eq(expected
, result
));
286 isl_int_clear(result
);
289 /* Use a triple that satisfies 'product = factor1 * factor2' to check the
290 * operations mul, divexact, tdiv, fdiv and cdiv.
292 static void int_test_product(isl_int product
, isl_int factor1
, isl_int factor2
)
294 int_test_divexact(factor1
, product
, factor2
);
295 int_test_divexact(factor2
, product
, factor1
);
297 int_test_mul(product
, factor1
, factor2
);
298 int_test_mul(product
, factor2
, factor1
);
301 static void int_test_add(isl_int expected
, isl_int lhs
, isl_int rhs
)
304 isl_int_init(result
);
306 isl_int_add(result
, lhs
, rhs
);
307 assert(isl_int_eq(expected
, result
));
309 isl_int_clear(result
);
312 static void int_test_sub(isl_int expected
, isl_int lhs
, isl_int rhs
)
315 isl_int_init(result
);
317 isl_int_sub(result
, lhs
, rhs
);
318 assert(isl_int_eq(expected
, result
));
320 isl_int_clear(result
);
323 /* Use a triple that satisfies 'sum = term1 + term2' to check the operations add
326 static void int_test_sum(isl_int sum
, isl_int term1
, isl_int term2
)
328 int_test_sub(term1
, sum
, term2
);
329 int_test_sub(term2
, sum
, term1
);
331 int_test_add(sum
, term1
, term2
);
332 int_test_add(sum
, term2
, term1
);
335 static void int_test_fdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
337 unsigned long rhsulong
;
339 isl_int_init(result
);
341 isl_int_fdiv_q(result
, lhs
, rhs
);
342 assert(isl_int_eq(expected
, result
));
344 if (isl_int_fits_ulong(rhs
)) {
345 rhsulong
= isl_int_get_ui(rhs
);
347 isl_int_fdiv_q_ui(result
, lhs
, rhsulong
);
348 assert(isl_int_eq(expected
, result
));
351 isl_int_clear(result
);
354 static void int_test_cdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
357 isl_int_init(result
);
359 isl_int_cdiv_q(result
, lhs
, rhs
);
360 assert(isl_int_eq(expected
, result
));
362 isl_int_clear(result
);
365 static void int_test_tdiv(isl_int expected
, isl_int lhs
, isl_int rhs
)
368 isl_int_init(result
);
370 isl_int_tdiv_q(result
, lhs
, rhs
);
371 assert(isl_int_eq(expected
, result
));
373 isl_int_clear(result
);
376 static void int_test_fdiv_r(isl_int expected
, isl_int lhs
, isl_int rhs
)
379 isl_int_init(result
);
381 isl_int_fdiv_r(result
, lhs
, rhs
);
382 assert(isl_int_eq(expected
, result
));
384 isl_int_clear(result
);
387 static void int_test_gcd(isl_int expected
, isl_int lhs
, isl_int rhs
)
390 isl_int_init(result
);
392 isl_int_gcd(result
, lhs
, rhs
);
393 assert(isl_int_eq(expected
, result
));
395 isl_int_gcd(result
, rhs
, lhs
);
396 assert(isl_int_eq(expected
, result
));
398 isl_int_clear(result
);
401 static void int_test_lcm(isl_int expected
, isl_int lhs
, isl_int rhs
)
404 isl_int_init(result
);
406 isl_int_lcm(result
, lhs
, rhs
);
407 assert(isl_int_eq(expected
, result
));
409 isl_int_lcm(result
, rhs
, lhs
);
410 assert(isl_int_eq(expected
, result
));
412 isl_int_clear(result
);
415 static int sgn(int val
)
424 static void int_test_cmp(int exp
, isl_int lhs
, isl_int rhs
)
428 assert(exp
== sgn(isl_int_cmp(lhs
, rhs
)));
430 if (isl_int_fits_slong(rhs
)) {
431 rhslong
= isl_int_get_si(rhs
);
432 assert(exp
== sgn(isl_int_cmp_si(lhs
, rhslong
)));
436 /* Test the comparison relations over two numbers.
437 * expected is the sign (1, 0 or -1) of 'lhs - rhs'.
439 static void int_test_cmps(isl_int expected
, isl_int lhs
, isl_int rhs
)
444 exp
= isl_int_get_si(expected
);
447 isl_int_sub(diff
, lhs
, rhs
);
448 assert(exp
== isl_int_sgn(diff
));
451 int_test_cmp(exp
, lhs
, rhs
);
452 int_test_cmp(-exp
, rhs
, lhs
);
455 static void int_test_abs_cmp(isl_int expected
, isl_int lhs
, isl_int rhs
)
459 exp
= isl_int_get_si(expected
);
460 assert(exp
== sgn(isl_int_abs_cmp(lhs
, rhs
)));
461 assert(-exp
== sgn(isl_int_abs_cmp(rhs
, lhs
)));
465 void (*fn
)(isl_int
, isl_int
, isl_int
);
466 char *expected
, *lhs
, *rhs
;
467 } int_binary_tests
[] = {
468 { &int_test_sum
, "0", "0", "0" },
469 { &int_test_sum
, "1", "1", "0" },
470 { &int_test_sum
, "2", "1", "1" },
471 { &int_test_sum
, "-1", "0", "-1" },
472 { &int_test_sum
, "-2", "-1", "-1" },
474 { &int_test_sum
, "2147483647", "1073741823", "1073741824" },
475 { &int_test_sum
, "-2147483648", "-1073741824", "-1073741824" },
477 { &int_test_sum
, "2147483648", "2147483647", "1" },
478 { &int_test_sum
, "-2147483648", "-2147483647", "-1" },
480 { &int_test_product
, "0", "0", "0" },
481 { &int_test_product
, "0", "0", "1" },
482 { &int_test_product
, "1", "1", "1" },
484 { &int_test_product
, "6", "2", "3" },
485 { &int_test_product
, "-6", "2", "-3" },
486 { &int_test_product
, "-6", "-2", "3" },
487 { &int_test_product
, "6", "-2", "-3" },
489 { &int_test_product
, "2147483648", "65536", "32768" },
490 { &int_test_product
, "-2147483648", "65536", "-32768" },
493 "4611686014132420609", "2147483647", "2147483647" },
495 "-4611686014132420609", "-2147483647", "2147483647" },
498 "4611686016279904256", "2147483647", "2147483648" },
500 "-4611686016279904256", "-2147483647", "2147483648" },
502 "-4611686016279904256", "2147483647", "-2147483648" },
504 "4611686016279904256", "-2147483647", "-2147483648" },
506 { &int_test_product
, "85070591730234615847396907784232501249",
507 "9223372036854775807", "9223372036854775807" },
508 { &int_test_product
, "-85070591730234615847396907784232501249",
509 "-9223372036854775807", "9223372036854775807" },
511 { &int_test_product
, "85070591730234615856620279821087277056",
512 "9223372036854775807", "9223372036854775808" },
513 { &int_test_product
, "-85070591730234615856620279821087277056",
514 "-9223372036854775807", "9223372036854775808" },
515 { &int_test_product
, "-85070591730234615856620279821087277056",
516 "9223372036854775807", "-9223372036854775808" },
517 { &int_test_product
, "85070591730234615856620279821087277056",
518 "-9223372036854775807", "-9223372036854775808" },
520 { &int_test_product
, "340282366920938463426481119284349108225",
521 "18446744073709551615", "18446744073709551615" },
522 { &int_test_product
, "-340282366920938463426481119284349108225",
523 "-18446744073709551615", "18446744073709551615" },
525 { &int_test_product
, "340282366920938463444927863358058659840",
526 "18446744073709551615", "18446744073709551616" },
527 { &int_test_product
, "-340282366920938463444927863358058659840",
528 "-18446744073709551615", "18446744073709551616" },
529 { &int_test_product
, "-340282366920938463444927863358058659840",
530 "18446744073709551615", "-18446744073709551616" },
531 { &int_test_product
, "340282366920938463444927863358058659840",
532 "-18446744073709551615", "-18446744073709551616" },
534 { &int_test_fdiv
, "0", "1", "2" },
535 { &int_test_fdiv_r
, "1", "1", "3" },
536 { &int_test_fdiv
, "-1", "-1", "2" },
537 { &int_test_fdiv_r
, "2", "-1", "3" },
538 { &int_test_fdiv
, "-1", "1", "-2" },
539 { &int_test_fdiv_r
, "-2", "1", "-3" },
540 { &int_test_fdiv
, "0", "-1", "-2" },
541 { &int_test_fdiv_r
, "-1", "-1", "-3" },
543 { &int_test_cdiv
, "1", "1", "2" },
544 { &int_test_cdiv
, "0", "-1", "2" },
545 { &int_test_cdiv
, "0", "1", "-2" },
546 { &int_test_cdiv
, "1", "-1", "-2" },
548 { &int_test_tdiv
, "0", "1", "2" },
549 { &int_test_tdiv
, "0", "-1", "2" },
550 { &int_test_tdiv
, "0", "1", "-2" },
551 { &int_test_tdiv
, "0", "-1", "-2" },
553 { &int_test_gcd
, "0", "0", "0" },
554 { &int_test_lcm
, "0", "0", "0" },
555 { &int_test_gcd
, "7", "0", "7" },
556 { &int_test_lcm
, "0", "0", "7" },
557 { &int_test_gcd
, "1", "1", "1" },
558 { &int_test_lcm
, "1", "1", "1" },
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
, "3", "6", "9" },
564 { &int_test_lcm
, "18", "6", "9" },
565 { &int_test_gcd
, "1", "14", "2147483647" },
566 { &int_test_lcm
, "15032385529", "7", "2147483647" },
567 { &int_test_gcd
, "2", "6", "-2147483648" },
568 { &int_test_lcm
, "6442450944", "6", "-2147483648" },
569 { &int_test_gcd
, "1", "6", "9223372036854775807" },
570 { &int_test_lcm
, "55340232221128654842", "6", "9223372036854775807" },
571 { &int_test_gcd
, "2", "6", "-9223372036854775808" },
572 { &int_test_lcm
, "27670116110564327424", "6", "-9223372036854775808" },
573 { &int_test_gcd
, "1", "18446744073709551616", "18446744073709551615" },
574 { &int_test_lcm
, "340282366920938463444927863358058659840",
575 "18446744073709551616", "18446744073709551615" },
577 { &int_test_cmps
, "0", "0", "0" },
578 { &int_test_abs_cmp
, "0", "0", "0" },
579 { &int_test_cmps
, "1", "1", "0" },
580 { &int_test_abs_cmp
, "1", "1", "0" },
581 { &int_test_cmps
, "-1", "-1", "0" },
582 { &int_test_abs_cmp
, "1", "-1", "0" },
583 { &int_test_cmps
, "-1", "-1", "1" },
584 { &int_test_abs_cmp
, "0", "-1", "1" },
586 { &int_test_cmps
, "-1", "5", "2147483647" },
587 { &int_test_abs_cmp
, "-1", "5", "2147483647" },
588 { &int_test_cmps
, "1", "5", "-2147483648" },
589 { &int_test_abs_cmp
, "-1", "5", "-2147483648" },
590 { &int_test_cmps
, "-1", "5", "9223372036854775807" },
591 { &int_test_abs_cmp
, "-1", "5", "9223372036854775807" },
592 { &int_test_cmps
, "1", "5", "-9223372036854775809" },
593 { &int_test_abs_cmp
, "-1", "5", "-9223372036854775809" },
596 /* Tests the isl_int_* function to give the expected results. Tests are
597 * grouped by the number of arguments they take.
599 * If small integer optimization is enabled, we also test whether the results
600 * are the same in small and big representation.
606 int_test_single_value();
608 for (i
= 0; i
< ARRAY_SIZE(int_unary_tests
); i
+= 1) {
609 invoke_alternate_representations_2args(
610 int_unary_tests
[i
].expected
, int_unary_tests
[i
].arg
,
611 int_unary_tests
[i
].fn
);
614 for (i
= 0; i
< ARRAY_SIZE(int_binary_tests
); i
+= 1) {
615 invoke_alternate_representations_3args(
616 int_binary_tests
[i
].expected
, int_binary_tests
[i
].lhs
,
617 int_binary_tests
[i
].rhs
, int_binary_tests
[i
].fn
);