diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-28 14:17:42 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-28 14:17:42 +0200 |
| commit | 1e5c862d8fa7b76b69b8125d454d8f8d6a9cde25 (patch) | |
| tree | 7eb709ba968b501e3c69c2892616b51d61e37c14 /src/utils | |
| parent | 7f24b27652ee6fa84e38f181cea57f319af0c204 (diff) | |
| download | nissy-core-1e5c862d8fa7b76b69b8125d454d8f8d6a9cde25.tar.gz nissy-core-1e5c862d8fa7b76b69b8125d454d8f8d6a9cde25.zip | |
Turns checks into assertions in utils/math.h
Diffstat (limited to '')
| -rw-r--r-- | src/utils/math.h | 73 |
1 files changed, 20 insertions, 53 deletions
diff --git a/src/utils/math.h b/src/utils/math.h index 4b1da12..95ec0aa 100644 --- a/src/utils/math.h +++ b/src/utils/math.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) | 3 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) |
| 4 | #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) | 4 | #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) |
| 5 | 5 | ||
| 6 | STATIC bool isperm(size_t, const uint8_t *); | ||
| 7 | STATIC int64_t permtoindex(size_t, const uint8_t *); | 6 | STATIC int64_t permtoindex(size_t, const uint8_t *); |
| 8 | STATIC void indextoperm(int64_t, size_t, uint8_t *); | 7 | STATIC void indextoperm(int64_t, size_t, uint8_t *); |
| 9 | STATIC int permsign(size_t, const uint8_t *); | 8 | STATIC int permsign(size_t, const uint8_t *); |
| @@ -11,18 +10,15 @@ STATIC int64_t digitstosumzero(size_t, const uint8_t *, uint8_t); | |||
| 11 | STATIC void sumzerotodigits(int64_t, size_t, uint8_t, uint8_t *); | 10 | STATIC void sumzerotodigits(int64_t, size_t, uint8_t, uint8_t *); |
| 12 | STATIC double intpow(double, uint64_t); | 11 | STATIC double intpow(double, uint64_t); |
| 13 | 12 | ||
| 13 | /* This code is only used for assertions in debug mode */ | ||
| 14 | #ifdef DEBUG | ||
| 15 | STATIC bool isperm(size_t, const uint8_t *); | ||
| 14 | STATIC bool | 16 | STATIC bool |
| 15 | isperm(size_t n, const uint8_t *a) | 17 | isperm(size_t n, const uint8_t *a) |
| 16 | { | 18 | { |
| 17 | size_t i; | 19 | size_t i; |
| 18 | bool aux[FACTORIAL_MAX+1]; | 20 | bool aux[FACTORIAL_MAX+1]; |
| 19 | 21 | ||
| 20 | if (n > (size_t)FACTORIAL_MAX) { | ||
| 21 | LOG("Error: won't compute 'isperm()' for n=%zu because" | ||
| 22 | " it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); | ||
| 23 | return false; | ||
| 24 | } | ||
| 25 | |||
| 26 | memset(aux, false, n); | 22 | memset(aux, false, n); |
| 27 | 23 | ||
| 28 | for (i = 0; i < n; i++) { | 24 | for (i = 0; i < n; i++) { |
| @@ -38,6 +34,7 @@ isperm(size_t n, const uint8_t *a) | |||
| 38 | 34 | ||
| 39 | return true; | 35 | return true; |
| 40 | } | 36 | } |
| 37 | #endif | ||
| 41 | 38 | ||
| 42 | STATIC int64_t | 39 | STATIC int64_t |
| 43 | permtoindex(size_t n, const uint8_t *a) | 40 | permtoindex(size_t n, const uint8_t *a) |
| @@ -45,14 +42,10 @@ permtoindex(size_t n, const uint8_t *a) | |||
| 45 | size_t i, j; | 42 | size_t i, j; |
| 46 | int64_t c, ret; | 43 | int64_t c, ret; |
| 47 | 44 | ||
| 48 | if (n > (size_t)FACTORIAL_MAX) { | 45 | DBG_ASSERT(n <= FACTORIAL_MAX, "Error: cannot compute permtoindex() " |
| 49 | LOG("Error: won't compute 'permtoindex()' for n=%zu because " | 46 | "for set of size %zu > %" PRId64 "\n", n, FACTORIAL_MAX); |
| 50 | "it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); | 47 | DBG_ASSERT(isperm(n, a), "Error: cannot compute permtoindex() for " |
| 51 | return -1; | 48 | "invalid permutation\n"); |
| 52 | } | ||
| 53 | |||
| 54 | if (!isperm(n, a)) | ||
| 55 | return -1; | ||
| 56 | 49 | ||
| 57 | for (i = 0, ret = 0; i < n; i++) { | 50 | for (i = 0, ret = 0; i < n; i++) { |
| 58 | for (j = i+1, c = 0; j < n; j++) | 51 | for (j = i+1, c = 0; j < n; j++) |
| @@ -70,17 +63,12 @@ indextoperm(int64_t p, size_t n, uint8_t *r) | |||
| 70 | size_t i, j; | 63 | size_t i, j; |
| 71 | uint8_t a[FACTORIAL_MAX+1]; | 64 | uint8_t a[FACTORIAL_MAX+1]; |
| 72 | 65 | ||
| 73 | if (n > FACTORIAL_MAX) { | 66 | DBG_ASSERT(n <= FACTORIAL_MAX, "Error: cannot compute indextoperm() " |
| 74 | LOG("Error: won't compute 'indextoperm()' for n=%zu because " | 67 | "for set of size %zu > %" PRId64 "\n", n, FACTORIAL_MAX); |
| 75 | "it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); | 68 | DBG_ASSERT(p >= 0 && p < factorial[n], "Error: invalid permutation " |
| 76 | goto indextoperm_error; | 69 | "index %" PRId64 " for set of size %zu\n", p, n); |
| 77 | } | ||
| 78 | 70 | ||
| 79 | memset(a, 0, n); | 71 | memset(a, 0, n); |
| 80 | |||
| 81 | if (p < 0 || p >= factorial[n]) | ||
| 82 | goto indextoperm_error; | ||
| 83 | |||
| 84 | for (i = 0; i < n; i++) { | 72 | for (i = 0; i < n; i++) { |
| 85 | for (j = 0, c = 0; c <= p / factorial[n-i-1]; j++) | 73 | for (j = 0, c = 0; c <= p / factorial[n-i-1]; j++) |
| 86 | c += a[j] ? 0 : 1; | 74 | c += a[j] ? 0 : 1; |
| @@ -89,13 +77,7 @@ indextoperm(int64_t p, size_t n, uint8_t *r) | |||
| 89 | p %= factorial[n-i-1]; | 77 | p %= factorial[n-i-1]; |
| 90 | } | 78 | } |
| 91 | 79 | ||
| 92 | if (!isperm(n, r)) | ||
| 93 | goto indextoperm_error; | ||
| 94 | |||
| 95 | return; | 80 | return; |
| 96 | |||
| 97 | indextoperm_error: | ||
| 98 | memset(r, UINT8_ERROR, n); | ||
| 99 | } | 81 | } |
| 100 | 82 | ||
| 101 | STATIC int | 83 | STATIC int |
| @@ -116,27 +98,17 @@ digitstosumzero(size_t n, const uint8_t *a, uint8_t b) | |||
| 116 | int64_t ret, p; | 98 | int64_t ret, p; |
| 117 | size_t i, sum; | 99 | size_t i, sum; |
| 118 | 100 | ||
| 119 | if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) { | 101 | DBG_ASSERT((n == 8 && b == 3 ) || (n == 12 && b == 2), |
| 120 | LOG("Error: won't compute 'sumzero' for n=%zu and b=%" PRIu8 | 102 | "Error: digitstosumzero() called with n=%zu and b=%" PRIu8 |
| 121 | " (use n=8 b=3 or n=12 b=2)\n", n, b); | 103 | " (use n=8 b=3 or n=12 b=2)\n", n, b); |
| 122 | return -1; | ||
| 123 | } | ||
| 124 | 104 | ||
| 125 | for (i = 1, ret = 0, p = 1, sum = 0; i < n; i++, p *= (int64_t)b) { | 105 | for (i = 1, ret = 0, p = 1, sum = 0; i < n; i++, p *= (int64_t)b) { |
| 126 | if (a[i] >= b) { | 106 | DBG_ASSERT(a[i] < b, "Error: digit %" PRIu8 |
| 127 | LOG("Error: digit %" PRIu8 " larger than maximum" | 107 | " > %" PRIu8 "in digitstosumzero()\n", a[i], b); |
| 128 | " (b=%" PRIu8 "\n", a[i], b); | ||
| 129 | return -1; | ||
| 130 | } | ||
| 131 | sum += a[i]; | 108 | sum += a[i]; |
| 132 | ret += p * (int64_t)a[i]; | 109 | ret += p * (int64_t)a[i]; |
| 133 | } | 110 | } |
| 134 | 111 | ||
| 135 | if ((sum + a[0]) % b != 0) { | ||
| 136 | LOG("Error: digits do not have sum zero modulo b\n"); | ||
| 137 | return -1; | ||
| 138 | } | ||
| 139 | |||
| 140 | return ret; | 112 | return ret; |
| 141 | } | 113 | } |
| 142 | 114 | ||
| @@ -146,11 +118,9 @@ sumzerotodigits(int64_t d, size_t n, uint8_t b, uint8_t *a) | |||
| 146 | uint8_t sum; | 118 | uint8_t sum; |
| 147 | size_t i; | 119 | size_t i; |
| 148 | 120 | ||
| 149 | if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) { | 121 | DBG_ASSERT((n == 8 && b == 3 ) || (n == 12 && b == 2), |
| 150 | LOG("Error: won't compute 'digits' for n=%zu and b=%" PRIu8 | 122 | "Error: sumzerotodigits() called with n=%zu and b=%" PRIu8 |
| 151 | " (use n=8 b=3 or n=12 b=2)\n", n, b); | 123 | " (use n=8 b=3 or n=12 b=2)\n", n, b); |
| 152 | goto sumzerotodigits_error; | ||
| 153 | } | ||
| 154 | 124 | ||
| 155 | for (i = 1, sum = 0; i < n; i++, d /= (int64_t)b) { | 125 | for (i = 1, sum = 0; i < n; i++, d /= (int64_t)b) { |
| 156 | a[i] = (uint8_t)(d % (int64_t)b); | 126 | a[i] = (uint8_t)(d % (int64_t)b); |
| @@ -159,9 +129,6 @@ sumzerotodigits(int64_t d, size_t n, uint8_t b, uint8_t *a) | |||
| 159 | a[0] = (b - (sum % b)) % b; | 129 | a[0] = (b - (sum % b)) % b; |
| 160 | 130 | ||
| 161 | return; | 131 | return; |
| 162 | |||
| 163 | sumzerotodigits_error: | ||
| 164 | memset(a, UINT8_ERROR, n); | ||
| 165 | } | 132 | } |
| 166 | 133 | ||
| 167 | STATIC double | 134 | STATIC double |
