From b3e9e62599532050fc776c5e8f076915b56c2235 Mon Sep 17 00:00:00 2001 From: David Faulkner Date: Fri, 7 Aug 2026 23:40:47 -0500 Subject: Import official C23 code examples for Modern C (Jens Gustedt, 2024) - Add official C source files, Makefile, c23-fallback.h, and LICENSE - Update README.md with study mirror notice --- rationals.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 rationals.c (limited to 'rationals.c') diff --git a/rationals.c b/rationals.c new file mode 100644 index 0000000..71beb7e --- /dev/null +++ b/rationals.c @@ -0,0 +1,218 @@ +#include "rationals.h" + +size_t gcd(size_t a, size_t b) [[__unsequenced__]]; + +rat rat_get(signed sign, size_t num, size_t denom) [[__unsequenced__]] { + rat ret = { + .sign = (sign < 0), + .num = num, + .denom = denom, + }; + return ret; +} + +rat rat_get_normal(rat x) [[__unsequenced__]] { + size_t c = gcd(x.num, x.denom); + x.num /= c; + x.denom /= c; + return x; +} + +rat rat_get_extended(rat x, size_t f) [[__unsequenced__]] { + x.num *= f; + x.denom *= f; + return x; +} + +rat rat_get_prod(rat x, rat y) [[__unsequenced__]] { + rat ret = { + .sign = (x.sign != y.sign), + .num = x.num * y.num, + .denom = x.denom * y.denom, + }; + return rat_get_normal(ret); +} + +rat rat_get_sum(rat x, rat y) [[__unsequenced__]] { + size_t c = gcd(x.denom, y.denom); + size_t ax = y.denom/c; + size_t bx = x.denom/c; + x = rat_get_extended(x, ax); /*@\label{rat_get_extended_x}*/ + y = rat_get_extended(y, bx); + assert(x.denom == y.denom); + + if (x.sign == y.sign) { + x.num += y.num; + } else if (x.num > y.num) { + x.num -= y.num; + } else { + x.num = y.num - x.num; + x.sign = !x.sign; + } + return rat_get_normal(x); +} + +rat rat_get_sum2(rat x, rat y) [[__unsequenced__]] { + size_t c = gcd(x.denom, y.denom); + size_t denom = (x.denom/c)*y.denom; + size_t num; + bool sign; + + size_t ab = x.num*(y.denom/c); + size_t ba = y.num*(x.denom/c); + if (x.sign == y.sign) { + num = ab + ba; + sign = x.sign; + } else { + if (ab < ba) { + num = ba - ab; + sign = y.sign; + } else { + num = ab - ba; + sign = x.sign; + } + } + rat ret = { + .sign = sign, + .num = num, + .denom = denom, + }; + return rat_get_normal(ret); +} + +rat rat_get_prod2(rat x, rat y) [[__unsequenced__]] { + size_t tmp = y.denom; + y.denom = x.denom; + x.denom = tmp; + x = rat_get_normal(x); + y = rat_get_normal(y); + rat ret = { + .sign = (x.sign != y.sign), + .num = x.num * y.num, + .denom = x.denom * y.denom, + }; + return ret; +} + +void rat_destroy(rat* rp) [[__unsequenced__]] { + if (rp) *rp = (rat){ }; +} + +rat* rat_init(rat* rp, + signed sign, + size_t num, + size_t denom) [[__unsequenced__]] { + if (rp) *rp = rat_get(sign, num, denom); + return rp; +} + +rat* rat_normalize(rat* rp) [[__unsequenced__]] { + if (rp) *rp = rat_get_normal(*rp); + return rp; +} + +rat* rat_extend(rat* rp, size_t f) [[__unsequenced__]] { + if (rp) *rp = rat_get_extended(*rp, f); + return rp; +} + +rat* rat_sumup(rat* rp, rat y) [[__unsequenced__]] { + size_t c = gcd(rp->denom, y.denom); + size_t ax = y.denom/c; + size_t bx = rp->denom/c; + rat_extend(rp, ax); /*@\label{rat_extend_x}*/ + y = rat_get_extended(y, bx); + assert(rp->denom == y.denom); + + if (rp->sign == y.sign) { + rp->num += y.num; + } else if (rp->num > y.num) { + rp->num -= y.num; + } else { + rp->num = y.num - rp->num; + rp->sign = !rp->sign; + } + return rat_normalize(rp); /*@\label{rat_normalize_x}*/ +} + +rat* rat_rma(rat* rp, rat x, rat y) [[__unsequenced__]] { + return rat_sumup(rp, rat_get_prod(x, y)); +} + +char const* rat_print(size_t len, char tmp[len], rat const* x) { + if (x) { + snprintf(tmp, len, "%c%zu/%zu", (x->sign ? '-' : '+'), x->num, x->denom); + } else { + tmp[0] = 0; + } + return tmp; +} + +#define RAT_PRINT_MAX 256 + +#define RAT_PRINT(X) rat_print(RAT_PRINT_MAX, (char[RAT_PRINT_MAX]){ }, (rat[1]){ (X) }) + +int main(void) { + rat third = rat_get(+1, 1, 3); + rat forth = rat_get(-1, 1, 4); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(third), + RAT_PRINT(rat_get_prod(third, third)), + RAT_PRINT(rat_get_prod(third, rat_get_prod(third, third))) + ); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_prod(forth, forth)), + RAT_PRINT(rat_get_prod(forth, rat_get_prod(forth, forth))) + ); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_prod(third, forth)), + RAT_PRINT(rat_get_prod(forth, rat_get_prod(third, forth))) + ); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(third), + RAT_PRINT(rat_get_prod2(third, third)), + RAT_PRINT(rat_get_prod2(third, rat_get_prod2(third, third))) + ); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_prod2(forth, forth)), + RAT_PRINT(rat_get_prod2(forth, rat_get_prod2(forth, forth))) + ); + printf("%s, prod is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_prod2(third, forth)), + RAT_PRINT(rat_get_prod2(forth, rat_get_prod2(third, forth))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(third), + RAT_PRINT(rat_get_sum(third, third)), + RAT_PRINT(rat_get_sum(third, rat_get_sum(third, third))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_sum(forth, forth)), + RAT_PRINT(rat_get_sum(forth, rat_get_sum(forth, forth))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_sum(third, forth)), + RAT_PRINT(rat_get_sum(forth, rat_get_sum(third, forth))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(third), + RAT_PRINT(rat_get_sum2(third, third)), + RAT_PRINT(rat_get_sum2(third, rat_get_sum2(third, third))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_sum2(forth, forth)), + RAT_PRINT(rat_get_sum2(forth, rat_get_sum2(forth, forth))) + ); + printf("%s, sum is %s, 3x %s\n", + RAT_PRINT(forth), + RAT_PRINT(rat_get_sum2(third, forth)), + RAT_PRINT(rat_get_sum2(forth, rat_get_sum2(third, forth))) + ); +} -- cgit v1.2.3