1 | #include <string.h> |
2 | #include <isl/val_gmp.h> |
3 | #include <isl_val_private.h> |
4 | |
5 | /* Return a reference to an isl_val representing the integer "z". |
6 | */ |
7 | __isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, mpz_t z) |
8 | { |
9 | isl_val *v; |
10 | |
11 | v = isl_val_alloc(ctx); |
12 | if (!v) |
13 | return NULL; |
14 | |
15 | isl_int_set(v->n, z); |
16 | isl_int_set_si(v->d, 1); |
17 | |
18 | return v; |
19 | } |
20 | |
21 | /* Return a reference to an isl_val representing the rational value "n"/"d". |
22 | */ |
23 | __isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, const mpz_t n, const mpz_t d) |
24 | { |
25 | isl_val *v; |
26 | |
27 | v = isl_val_alloc(ctx); |
28 | if (!v) |
29 | return NULL; |
30 | |
31 | isl_int_set(v->n, n); |
32 | isl_int_set(v->d, d); |
33 | |
34 | return isl_val_normalize(v); |
35 | } |
36 | |
37 | /* Extract the numerator of a rational value "v" in "z". |
38 | * |
39 | * If "v" is not a rational value, then the result is undefined. |
40 | */ |
41 | int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z) |
42 | { |
43 | if (!v) |
44 | return -1; |
45 | if (!isl_val_is_rat(v)) |
46 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
47 | "expecting rational value" , return -1); |
48 | mpz_set(z, v->n); |
49 | return 0; |
50 | } |
51 | |
52 | /* Extract the denominator of a rational value "v" in "z". |
53 | * |
54 | * If "v" is not a rational value, then the result is undefined. |
55 | */ |
56 | int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z) |
57 | { |
58 | if (!v) |
59 | return -1; |
60 | if (!isl_val_is_rat(v)) |
61 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
62 | "expecting rational value" , return -1); |
63 | mpz_set(z, v->d); |
64 | return 0; |
65 | } |
66 | |
67 | /* Return a reference to an isl_val representing the unsigned |
68 | * integer value stored in the "n" chunks of size "size" at "chunks". |
69 | * The least significant chunk is assumed to be stored first. |
70 | */ |
71 | __isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n, |
72 | size_t size, const void *chunks) |
73 | { |
74 | isl_val *v; |
75 | |
76 | v = isl_val_alloc(ctx); |
77 | if (!v) |
78 | return NULL; |
79 | |
80 | mpz_import(v->n, n, -1, size, 0, 0, chunks); |
81 | isl_int_set_si(v->d, 1); |
82 | |
83 | return v; |
84 | } |
85 | |
86 | /* Return the number of chunks of size "size" required to |
87 | * store the absolute value of the numerator of "v". |
88 | */ |
89 | isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size) |
90 | { |
91 | if (!v) |
92 | return isl_size_error; |
93 | |
94 | if (!isl_val_is_rat(v)) |
95 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
96 | "expecting rational value" , return isl_size_error); |
97 | |
98 | size *= 8; |
99 | return (mpz_sizeinbase(v->n, 2) + size - 1) / size; |
100 | } |
101 | |
102 | /* Store a representation of the absolute value of the numerator of "v" |
103 | * in terms of chunks of size "size" at "chunks". |
104 | * The least significant chunk is stored first. |
105 | * The number of chunks in the result can be obtained by calling |
106 | * isl_val_n_abs_num_chunks. The user is responsible for allocating |
107 | * enough memory to store the results. |
108 | * |
109 | * In the special case of a zero value, isl_val_n_abs_num_chunks will |
110 | * return one, while mpz_export will not fill in any chunks. We therefore |
111 | * do it ourselves. |
112 | */ |
113 | isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size, |
114 | void *chunks) |
115 | { |
116 | if (!v || !chunks) |
117 | return isl_stat_error; |
118 | |
119 | if (!isl_val_is_rat(v)) |
120 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
121 | "expecting rational value" , return isl_stat_error); |
122 | |
123 | mpz_export(chunks, NULL, -1, size, 0, 0, v->n); |
124 | if (isl_val_is_zero(v)) |
125 | memset(s: chunks, c: 0, n: size); |
126 | |
127 | return isl_stat_ok; |
128 | } |
129 | |