diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-07-05 19:23:58 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-07-05 19:23:58 +0200 |
| commit | 5fb58d73581256c64d47250c5544d1cbf22f79c3 (patch) | |
| tree | 2d5774c0e31dc095cc70a010cad908e431736233 /src/utils.h | |
| parent | 518d98ad5f9eec0cf4124375bdbb84d1296b3f3f (diff) | |
| download | nissy-core-5fb58d73581256c64d47250c5544d1cbf22f79c3.tar.gz nissy-core-5fb58d73581256c64d47250c5544d1cbf22f79c3.zip | |
Added more math utilities
Diffstat (limited to '')
| -rw-r--r-- | src/utils.h | 58 |
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 |
| 8 | factorial(int64_t n) | 10 | factorial(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 | ||
| 130 | digitstosumzero(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 | ||
| 160 | sumzerotodigits(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 | |||
| 179 | digitstosumzero_error: | ||
| 180 | memset(a, _error, n); | ||
| 181 | } | ||
