From 7debbd67ade4365483d169dd220c221ed5898a4e Mon Sep 17 00:00:00 2001 From: cpmachado <40689339+cpmachado@users.noreply.github.com> Date: Mon, 21 Oct 2024 00:50:51 +0100 Subject: [PATCH] Detect overflow (#5) * Detect overflow clauses, abort on failure * Improve capability with gcd to normalise ratio --- src/egc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/egc.c b/src/egc.c index db6aec0..9c44ca7 100644 --- a/src/egc.c +++ b/src/egc.c @@ -129,15 +129,45 @@ void version(void) { ": cpmachado\n"); } +int64_t gcdInt64(int64_t a, int64_t b) { + int64_t c; + while (b > 0) { + if (a > b) { + c = a; + a = b; + b = c % a; + } else { + b = b % a; + } + } + return a; +} + int32_t computeUnitaryFractions(int64_t num, int64_t den, int64_t *s) { int64_t n, i; s[0] = 0; for (i = 1; num > 1; i++) { + /* normalise denominator and numerator */ + n = gcdInt64(num, den); + num = num / n; + den = den / n; + + /* The real n */ n = den / num + (den % num > 0); s[i] = n; + if (INT64_MAX / n < num) { + fprintf(stderr, "Overflow detected\n"); + printf("num = %ld, n = %ld\n", num, n); + exit(EXIT_FAILURE); + } num = num * n - den; + if (INT64_MAX / n < den) { + fprintf(stderr, "Overflow detected\n"); + printf("den = %ld, n = %ld\n", den, n); + exit(EXIT_FAILURE); + } den = den * n; }