start converting numbers to rational numbers
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.ejs": "html",
|
||||
"stdio.h": "c"
|
||||
"stdio.h": "c",
|
||||
"stdbool.h": "c",
|
||||
"string.h": "c"
|
||||
}
|
||||
}
|
||||
2
Makefile
2
Makefile
@@ -1,3 +1,3 @@
|
||||
build:
|
||||
mkdir -p bin
|
||||
gcc -O3 -o bin/cargon $(shell find src -name '*.c') -Wall -Wextra -Werror
|
||||
gcc -O3 -o bin/cargon $(shell find src -name '*.c') -lm -Wall -Wextra -Werror
|
||||
BIN
bin/cargon
BIN
bin/cargon
Binary file not shown.
39
src/main.c
39
src/main.c
@@ -1,32 +1,29 @@
|
||||
#include "string/string.h"
|
||||
#include "number/number.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,108 @@
|
||||
#include "number.h"
|
||||
#include "../string/string.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
#define CLONESTRING_HNUMBER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user