From a71071d8580580724026b90bc1221050f525b22d Mon Sep 17 00:00:00 2001 From: William Bell Date: Wed, 8 May 2024 00:38:02 +0100 Subject: [PATCH] start converting numbers to rational numbers --- .vscode/settings.json | 4 +- Makefile | 2 +- bin/cargon | Bin 16360 -> 17176 bytes src/main.c | 39 ++++++++-------- src/number/number.c | 103 +++++++++++++++++++++++++++++++++++++++++- src/number/number.h | 8 +++- 6 files changed, 129 insertions(+), 27 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1de26dd..bca80c1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "files.associations": { "*.ejs": "html", - "stdio.h": "c" + "stdio.h": "c", + "stdbool.h": "c", + "string.h": "c" } } \ No newline at end of file diff --git a/Makefile b/Makefile index b75a8e0..f6378c6 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,3 @@ build: mkdir -p bin - gcc -O3 -o bin/cargon $(shell find src -name '*.c') -Wall -Wextra -Werror \ No newline at end of file + gcc -O3 -o bin/cargon $(shell find src -name '*.c') -lm -Wall -Wextra -Werror \ No newline at end of file diff --git a/bin/cargon b/bin/cargon index c3bed338182b7af967bb31895b2ac7bab37bc963..e010e0029963ebcb36eb0f8bac63617fa697a66b 100755 GIT binary patch literal 17176 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 AW&i*H delta 3092 zcmZWrdrVu`89(>h2HSvNJp3quYoJ-uCD(RdJc6--lwPv5p^KuiZYy|T0ux}@I9Y?# z*d1vXkFb$^QA?yrZKQRZ(y9$&n_B(}8C_FNTZFbhhN_J+bq}vugGn=q6cX<{_nu2K z?_AyUJKyj7&g(npJLgQj%%u~P4qMVn#GeS5*6Nt8^#8vM~&SG%$E@Yi2^cm8(aiS2*<41TQHCeU%yUg@w1p>>pL zQ+_1A!wJ)TIhO~V*3NC0^NZlq+QF;Uf>v9?70cYya^5B9opSz5YQ^=*4J5EMOW{fRO0%_z3BXg~MbhJTw$J5e8en7oN`FVvoiK zhU0yd?unixg9G305l158KDd%!V%oijJaMSKrL}99xJ%p%leJsmjlAs%IyntamEZh0 zqGe^ua`B=(g`DY*u<{&V2g&NcEW`x`de!DRo^+&6}+< zaS92uHCUK_TthX#LF@QIX?$;+M>b5KlIbOB!f!xJ-(1>Hn@oM2{?C1iw@{I(|AgebbW`5^2T~K1dLOBqH~S_*u(=ODA`)_^Pc&Da zMjPyU!at3SG@-jpp?)o1Dvj&zV_eVy8nVmg$|SX$XNdMM%JzFlVcb^E{T_a9tN5}X zDRO-GQEAM7nTC{<`g^=c8uynWpDmq2D&2#l{yFoNU@DU4KGeIw`e=MS0tp zFXYennJW(va`Z@Q{VL^T=ia)99_U$5Iizd<)S&Cqf4K*4M;ZUdJ*am?`A;_BO^2JG z+khL6R{rJ&6g%Il`D`8QO!RY7Y9;O4pdP$NCuEgUpGv7ET$yyi27KadDjG+_L#dVa z)CcM0I*6`qeBU~By1vBw*WpE1IUiYv*IXXHX&n|^c7E^r%)eZA-AuBkTX$a2CfY&+ zgW+Bw9uY!=gOQ$4JS<>bMPet(15M9hWH>C0#4+rSk;AcpV*|sXK_)i{RgaET8A&U( z>CGVpgR!Wv0KK3jL6M~}_OwIz8vPTI*kG@lDG2w7Wmp zHMc!4a|yn$TXYu&C29xduQ=q z!!f$3Jxeu+KcVGSuvJ&Neut%PIDCu(IhA9+jDO84JXP(=!y|~CUWMW6wu(bo{17ec zWjiI?hCnBlS%p7TZ_S&;V#)29`_;cT%tQ;4oJ&1$)bj=PavCD=>COu4g;GUyGI{}= zVkNf-^`eJQ>fk$K1;0e#2VxVSA@EzV!aYTg5KIinoN`HQo@0w(@OY|{jK$!HP;0eU z^n@%wn+MN$e#kHT@hT}h@9kihEg|Z07lLW;3bzcGe0F|PfLY&GSo1lcTkC);I{Bh- z9>hik;vgMC+QWnND|(%@Uq`}%+Wz1J4K3ZkpI$6UcHXKBvqX8`OjL(ZTblkRUrtG# zw$zHP<(|SC_^Z#(mC5;bn)@1YRJ8pLwwu19G(#lh>3DKSdlcMz>`uCZR^G8WeO8G) zC$~99we$)S6kf~J=aHvyajBUWocKI#aO0|Q(9nAS>suJ*;Q@iErd7mUxn-Z^}1&>6kXX0*!ei&UPC z?QzCCk*9vk9o3`A3xvQ7Z`B2`T!s6r*!m1@g)gLTQ4(;qBNqCY2tNEe7^!Wr(`UxR zBia_@ z{jHJSFih1q+hTa0o(SW6DmD;3A|IllZ`cj(4eps28ala|#r*=u)xh1x06)b+gI}~J z*>h9HC2(tt;jF*h`Ya1K6|3Mqzh{dYgenHvtZC?SplhnOs==!w#(k5=riQqR82O`3 zr}S4?b-2`I2YbM3Q5|9h~)-GIlsCMb=nsD=8V z2hu?cJRkHLT==Um?df8Eh qjfLQ7abOK!OTc)B>H4)W+Op4>*`t_t^Dv8IN39~3aqz|divI#PfT{)n diff --git a/src/main.c b/src/main.c index 95ea820..17bda6e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,32 +1,29 @@ #include "string/string.h" +#include "number/number.h" #include #include #include +void initialize() { + initNumber(); +} + +void cleanup() { + cleanupNumber(); +} + int main() { - char* str = malloc(100 * sizeof(char)); - if (str == NULL) { - printf("Failed to allocate memory\n"); + initialize(); + char *code = "1.2e20"; + struct number mynum = translateNumber(code); + if (mynum.denominator == 0) { + printf("Invalid number\n"); return 1; } - strcpy(str, " \t\n\r\f\vHello, World! \t\n\r\f\v"); - char* clone = cloneString(str); - - if (clone == NULL) { - printf("Failed to clone string\n"); - return 1; - } - - stripString(clone, WHITE_SPACE); - - printf("Original string: \"%s\"\n", str); - - free(str); - - - printf("Cloned string: \"%s\"\n", clone); - free(clone); - + double f = 1.0 * mynum.numerator / mynum.denominator; + printf("Numerator: %ld\n", mynum.numerator); + printf("Denominator: %lu\n", mynum.denominator); + printf("Float: %lf\n", f); return 0; } diff --git a/src/number/number.c b/src/number/number.c index 861eb98..63ddef0 100644 --- a/src/number/number.c +++ b/src/number/number.c @@ -1,9 +1,108 @@ #include "number.h" +#include "../string/string.h" #include +#include +#include +#include +#include -struct number translateNumber(char *code) { +regex_t numberCompile; + +void initNumber() +{ + int compileError; + compileError = regcomp(&numberCompile, "^( *)(-)?(((([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))(e((\\-|\\+)?([0-9]+)))?))( *)$", REG_EXTENDED); + if (compileError) + { + char errorBuffer[1024]; + regerror(compileError, &numberCompile, errorBuffer, sizeof(errorBuffer)); + fprintf(stderr, "Error compiling regex: %s\n", errorBuffer); + exit(1); + } +} + +void cleanupNumber() +{ + regfree(&numberCompile); +} + +int gcd(int64_t a, int64_t b) +{ + while (b != 0) + { + int temp = b; + b = a % b; + a = temp; + } + return a; +} + +void simplifyFraction(int64_t *numerator, int64_t *denominator) +{ + int common_divisor = gcd(*numerator, *denominator); + *numerator /= common_divisor; + *denominator /= common_divisor; +} + +void doubleToFraction(double num, int64_t *numerator, uint64_t *denominator) { + int currentSign = (num < 0) ? -1 : 1; + num = fabs(num); + + double tolerance = 1.0e-10; + double h1 = 1, h2 = 0, k1 = 0, k2 = 1; + double b = num; + do { + double a = floor(b); + double aux = h1; + h1 = a * h1 + h2; + h2 = aux; + aux = k1; + k1 = a * k1 + k2; + k2 = aux; + b = 1 / (b - a); + } while (fabs(num - h1 / k1) > num * tolerance); + + *numerator = (int64_t)(h1 * currentSign); + *denominator = (uint64_t)k1; +} + +struct number translateNumber(char *code) +{ + char *codeClone = cloneString(code); + stripString(codeClone, WHITE_SPACE); + int reti = regexec(&numberCompile, codeClone, 0, NULL, 0); + if (reti == REG_NOMATCH) + { + return (struct number){ + .numerator = 0, + .denominator = 0 + }; + } struct number num; - num.sign = code[0] == '-' ? 1 : 0; + num.numerator = 0; + num.denominator = 1; + + double coefficient = 0; + int exponent = 0; + + char *e = strchr(codeClone, 'e'); + if (e) { + *e = '\0'; + e++; + if (*e == '+') e++; + exponent = atoi(e); + } + + coefficient = atof(codeClone); + + doubleToFraction(coefficient, &num.numerator, &num.denominator); + + if (exponent > 0) { + num.numerator *= (int64_t)pow(10, exponent); + } else if (exponent < 0) { + num.denominator *= (int64_t)pow(10, -exponent); + } + return num; } diff --git a/src/number/number.h b/src/number/number.h index 0e93d1e..8fff0b1 100644 --- a/src/number/number.h +++ b/src/number/number.h @@ -2,13 +2,17 @@ #define CLONESTRING_HNUMBER_H #include +#include + #include struct number { - uint8_t sign; - uint64_t numerator; + int64_t numerator; uint64_t denominator; }; struct number translateNumber(char *code); +void initNumber(); +void cleanupNumber(); + #endif // NUMBER_H