diff --git a/src/exponent.c b/src/exponent.c index a195240..bbe2221 100644 --- a/src/exponent.c +++ b/src/exponent.c @@ -1,7 +1,9 @@ #include #include +#include #include "exponent.h" +#include "logarithmus.h" double absD(double x){ if(x<0){ @@ -35,13 +37,13 @@ double powerD(double exp, double base){ } }else if(base > 0.0){ if(exp>=0.0){ - return exponential(exp*logN(base, 0.00000001)); + return exponential(exp*logN(base)); } else{ if (base == 0.0){ return -1.0; } - return (1.0 / exponential((-1*exp)*logN(base, 0.00000001))); + return (1.0 / exponential((-1*exp)*logN(base))); } } return -1.0; @@ -68,19 +70,3 @@ double exponential(double x){ return sum; } - - -double logN(double x, double eps){ - if(x <= 0){ - return -1.0; - } - double yn = x - 1.0; - double yn1 = yn; - - do{ - yn = yn1; - yn1 = yn + 2 * (x - exponential(yn)) / (x + exponential(yn)); - } while (absD(yn - yn1) > eps); - - return yn1; -} \ No newline at end of file diff --git a/src/exponent.h b/src/exponent.h index 14714d9..9b53200 100644 --- a/src/exponent.h +++ b/src/exponent.h @@ -4,6 +4,6 @@ double p(double exp, double base); double powerD(double exp, double base); double exponential(double x); -double logN(double x, double eps); +double absD(double x); #endif // exponent.h \ No newline at end of file diff --git a/src/logarithmus.c b/src/logarithmus.c new file mode 100644 index 0000000..1c613e5 --- /dev/null +++ b/src/logarithmus.c @@ -0,0 +1,65 @@ +#include +#include + +#include "logarithmus.h" +#include "exponent.h" + +double logX(double base, double value){ + if(base == 1.0 || base <= 0.0 || value <= 0.0){ + return -1.0; + } + return(logN(value)/logN(base)); +} + +double log10(double value){ + return logX(10.0, value); +} + +double log2(double value){ + return logX(2.0, value); +} +double lns(double x, double eps){ + double yn = x - 1.0; + double yn1 = yn; + + do{ + yn = yn1; + yn1 = yn + 2 * (x - exponential(yn)) / (x + exponential(yn)); + } while (absD(yn - yn1) > eps); + + return yn1; +} + +double lnb(double x){ + int power_adjust = 0; + while (x > 1.0) { + x /= exponential(1); + power_adjust++; + } + while (x < .25) { + x *= exponential(1); + power_adjust--; + } + + x -= 1.0; + double t = 0.0, s = 1.0, z = x; + for (int k=1; k<=100; k++) { + t += z * s / k; + z *= x; + s = -s; + } + return t + power_adjust; +} + +double logN(double x){ + if(x <= 0){ + return -1.0; + } + if(x<200){ + return lns(x, 0.00000001); + } + else{ + return lnb(x); + } +} + diff --git a/src/logarithmus.h b/src/logarithmus.h new file mode 100644 index 0000000..113c48b --- /dev/null +++ b/src/logarithmus.h @@ -0,0 +1,9 @@ +#ifndef LOGARITHMUS_H +#define LOGARITHMUS_H + +double logN(double x); +double logX(double b, double a); +double log10(double a); +double log2(double a); + +#endif // logarithmus.h \ No newline at end of file diff --git a/test/test_exponent.c b/test/test_exponent.c index ec19222..ae49c01 100644 --- a/test/test_exponent.c +++ b/test/test_exponent.c @@ -3,6 +3,7 @@ #include "unity.h" #include "exponent.h" +#include "logarithmus.h" void setUp(void) { @@ -122,29 +123,4 @@ void test_Exponent_with_negative_number(void){ TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.135335, r2); } -void test_ln_with_positive_number(void){ - double r1, r2, r3; - - r1 = logN(1.0, 0.000001); - r2 = logN(10.0, 0.000001); - r3 = logN(2.5, 0.000001); - - TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0, r1); - TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.302585, r2); - TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.916290, r3); -} - -void test_ln_with_zero_and_negative_numbers(void){ - double r1, r2, r3; - - r1 = logN(0.0, 0.000001); - r2 = logN(-1.0, 0.000001); - r3 = logN(-2.5, 0.000001); - - TEST_ASSERT_EQUAL_DOUBLE(-1.0, r1); - TEST_ASSERT_EQUAL_DOUBLE(-1.0, r2); - TEST_ASSERT_EQUAL_DOUBLE(-1.0, r3); -} - - #endif // TEST \ No newline at end of file diff --git a/test/test_logarithmus.c b/test/test_logarithmus.c new file mode 100644 index 0000000..0f7aba1 --- /dev/null +++ b/test/test_logarithmus.c @@ -0,0 +1,119 @@ +#ifdef TEST + +#include "unity.h" + +#include "logarithmus.h" +#include "exponent.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_ln_with_positive_number(void){ + double r1, r2, r3; + + r1 = logN(1.0); + r2 = logN(10.0); + r3 = logN(2.5); + + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0, r1); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.302585, r2); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.916290, r3); +} + +void test_ln_with_zero_and_negative_numbers(void){ + double r1, r2, r3; + + r1 = logN(0.0); + r2 = logN(-1.0); + r3 = logN(-2.5); + + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r1); + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r2); + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r3); +} + +void test_logarithmic_function_with_edge_cases(void){ + double r1, r2, r3, r4; + + r1 = logX(0, 10.0); + r2 = logX(-1.0, 9.0); + r3 = logX(1.0, 18.0); + r4 = logX(3.0, 0.0); + + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r1); + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r2); + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r3); + TEST_ASSERT_EQUAL_DOUBLE(-1.0, r4); +} + +void test_logarithmic_function_with_integers(void){ + double r1, r2, r3, r4; + + r1 = logX(0.5, 48.0); + r2 = logX(2.0, 8.0); + r3 = logX(3.2, 18.0); + r4 = logX(6.0, 36.0); + + TEST_ASSERT_DOUBLE_WITHIN(0.000001, -5.584962, r1); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 3.0, r2); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.484950, r3); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.0, r4); +} + +void test_logarithmic_function_with_decimals(void){ + double r1, r2, r3, r4; + + r1 = logX(0.1289, 26.5); + r2 = logX(7.64, 8.314); + r3 = logX(3.0, 2.4587); + r4 = logX(9.0, 94.6584); + + TEST_ASSERT_DOUBLE_WITHIN(0.000001, -1.599607, r1); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 1.041577, r2); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.818881, r3); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.070919, r4); +} + +void test_logarithmic_function_to_base_10(void){ + double r1, r2, r3, r4, r5, r6; + + r1 = log10(100.0); + r2 = log10(100.6479); + r3 = log10(10.587); + r4 = log10(4.341); + r5 = log10(0.34979); + r6 = log10(1.0); + + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.0, r1); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 2.002804, r2); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 1.024772, r3); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.637589, r4); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, -0.456192, r5); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.0, r6); +} + +void test_logarithmic_function_to_base_2(void){ + double r1, r2, r3, r4, r5, r6; + + r1 = log2(1024.0); + r2 = log2(1024.8742); + r3 = log2(900.587); + r4 = log2(78.341); + r5 = log2(0.34979); + r6 = log2(1.0); + + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 10.0, r1); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 10.001231, r2); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 9.814721, r3); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 6.291695, r4); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, -1.515439, r5); + TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.0, r6); +} + + +#endif // TEST \ No newline at end of file