diff --git a/init.c b/init.c index c608d4d..1ed3054 100644 --- a/init.c +++ b/init.c @@ -21,4 +21,6 @@ void init() addSymbolInternal("*", &multiply); addSymbolInternal("/", ÷); addSymbolInternal("навод", "e); + addSymbolInternal("тачно->нетачно", &exactToInexact); + addSymbolInternal("нетачно->тачно", &inexactToExact); } diff --git a/internals.c b/internals.c index a2e2b91..69ac06b 100644 --- a/internals.c +++ b/internals.c @@ -131,6 +131,50 @@ object divide(object parameters) return result; } +object exactToInexact(object parameters) +{ + object result; + + if (listLength(parameters) != 1) + { + TYPE(result) = errorObject; + ERR(result) = argumentNumberError; + } + else if (TYPE(CAR(parameters)) != numberObject) + { + TYPE(result) = errorObject; + ERR(result) = typeError; + } + else + { + result = exactToInexactNum(CAR(parameters)); + } + + return result; +} + +object inexactToExact(object parameters) +{ + object result; + + if (listLength(parameters) != 1) + { + TYPE(result) = errorObject; + ERR(result) = argumentNumberError; + } + else if (TYPE(CAR(parameters)) != numberObject) + { + TYPE(result) = errorObject; + ERR(result) = typeError; + } + else + { + result = inexactToExactNum(CAR(parameters)); + } + + return result; +} + object quote(object parameters) { object result; diff --git a/internals.h b/internals.h index 3a6fa3b..0a0f1ba 100644 --- a/internals.h +++ b/internals.h @@ -4,4 +4,6 @@ object add(object parameters); object subtract(object parameters); object multiply(object parameters); object divide(object parameters); +object exactToInexact(object parameters); +object inexactToExact(object parameters); object quote(object parameters); diff --git a/util.c b/util.c index a8e03f7..3dc0993 100644 --- a/util.c +++ b/util.c @@ -1,5 +1,7 @@ #include +#include #include +#include #include "util.h" @@ -96,6 +98,30 @@ object exactToInexactNum(object a) return result; } +object inexactToExactNum(object a) +{ + object result = copyObject(a); + + if (TYPE(result) == numberObject && NUM_TYPE(result) == realNum) + { + long long int divisor = 1; + while (NUM_REAL(result) != floorl(NUM_REAL(result)) && + divisor <= INT_MAX) + { + NUM_REAL(result) *= 10.0L; + divisor *= 10LL; + } + + NUM_TYPE(result) = fractionNum; + NUM_NUMER(result) = (long long int) floorl(NUM_REAL(result)); + NUM_DENOM(result) = divisor; + + result = shortenFractionNum(result); + } + + return result; +} + long long int gcd(long long int a, long long int b) /* највећи заједнички делилац */ { diff --git a/util.h b/util.h index eda3c07..9c00060 100644 --- a/util.h +++ b/util.h @@ -84,6 +84,7 @@ object copyObject(object input); object longlongToNumber(long long int input); object shortenFractionNum(object a); object exactToInexactNum(object a); +object inexactToExactNum(object a); object plusNum(object a, object b); object minusNum(object a); object timesNum(object a, object b);