aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-07-05 19:23:58 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-07-05 19:23:58 +0200
commit5fb58d73581256c64d47250c5544d1cbf22f79c3 (patch)
tree2d5774c0e31dc095cc70a010cad908e431736233 /src
parent518d98ad5f9eec0cf4124375bdbb84d1296b3f3f (diff)
downloadnissy-core-5fb58d73581256c64d47250c5544d1cbf22f79c3.tar.gz
nissy-core-5fb58d73581256c64d47250c5544d1cbf22f79c3.zip
Added more math utilities
Diffstat (limited to 'src')
-rw-r--r--src/utils.h58
1 files changed, 57 insertions, 1 deletions
diff --git a/src/utils.h b/src/utils.h
index 0c0b4d1..3d35437 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -3,6 +3,8 @@ _static bool isperm(uint8_t *, int64_t);
3_static int64_t permtoindex(uint8_t *, int64_t); 3_static int64_t permtoindex(uint8_t *, int64_t);
4_static void indextoperm(int64_t, int64_t, uint8_t *); 4_static void indextoperm(int64_t, int64_t, uint8_t *);
5_static int permsign(uint8_t *, int64_t); 5_static int permsign(uint8_t *, int64_t);
6_static int64_t digitstosumzero(uint8_t *, uint8_t, uint8_t);
7_static void sumzerotodigits(int64_t, uint8_t, uint8_t, uint8_t *);
6 8
7_static int64_t 9_static int64_t
8factorial(int64_t n) 10factorial(int64_t n)
@@ -39,7 +41,7 @@ isperm(uint8_t *a, int64_t n)
39 memset(aux, false, n); 41 memset(aux, false, n);
40 42
41 for (i = 0; i < n; i++) { 43 for (i = 0; i < n; i++) {
42 if (a[i] < 0 || a[i] >= n) 44 if (a[i] >= n)
43 return false; 45 return false;
44 else 46 else
45 aux[a[i]] = true; 47 aux[a[i]] = true;
@@ -123,3 +125,57 @@ permsign(uint8_t *a, int64_t n)
123 125
124 return ret % 2; 126 return ret % 2;
125} 127}
128
129_static int64_t
130digitstosumzero(uint8_t *a, uint8_t n, uint8_t b)
131{
132 int64_t ret, p;
133 uint8_t i, sum;
134
135 if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) {
136 LOG("Won't compute 'sumzero' for n=%" PRIu8 "and b=%" PRIu8
137 " (use n=8 b=3 or n=12 b=2)\n", n, b);
138 return -1;
139 }
140
141 for (i = 1, ret = 0, p = 1; i < n; i++, p *= (int64_t)b) {
142 if (a[i] >= b) {
143 LOG("Error: digit %" PRIu8 " larger than maximum"
144 " (b=%" PRIu8 "\n", a[i], b);
145 return -1;
146 }
147 sum += a[i];
148 ret += p * (int64_t)a[i];
149 }
150
151 if ((sum + a[0]) % b != 0) {
152 LOG("Error: digits do not have sum zero modulo b\n");
153 return -1;
154 }
155
156 return ret;
157}
158
159_static void
160sumzerotodigits(int64_t d, uint8_t n, uint8_t b, uint8_t *a)
161{
162 uint8_t sum;
163 int64_t i;
164
165 if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) {
166 LOG("Won't compute 'digits' for n=%" PRIu8 "and b=%" PRIu8
167 " (use n=8 b=3 or n=12 b=2)\n");
168 goto digitstosumzero_error;
169 }
170
171 for (i = 1; i < n; i++, d /= (int64_t)b) {
172 a[i] = (uint8_t)(d % (int64_t)b);
173 sum += a[i];
174 }
175 a[0] = (b - (sum % b)) % b;
176
177 return;
178
179digitstosumzero_error:
180 memset(a, _error, n);
181}

Generated with cgit - Back to sebastiano.tronto.net