Browse Source
Merge branch 'Exponent' into 'master'
Merge branch 'Exponent' into 'master'
Exponent See merge request fdai7848/Linkes-Twix!2master
fdai7848
11 months ago
3 changed files with 245 additions and 0 deletions
@ -0,0 +1,86 @@ |
|||||
|
#include <stdio.h> |
||||
|
#include <limits.h> |
||||
|
|
||||
|
#include "exponent.h" |
||||
|
|
||||
|
double absD(double x){ |
||||
|
if(x<0){ |
||||
|
return -1 * x; |
||||
|
} |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
double p(double exp, double base){ |
||||
|
double prod = 1.0; |
||||
|
if(exp==0.0){ |
||||
|
return 1; |
||||
|
}else{ |
||||
|
for(int i = 1; i <= (int) exp; i++){ |
||||
|
prod *= base; |
||||
|
} |
||||
|
return prod; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
double powerD(double exp, double base){ |
||||
|
if(absD(exp) - ((int) absD(exp)) < 0.000001){ |
||||
|
if(exp>=0.0){ |
||||
|
return p(exp, base); |
||||
|
} |
||||
|
else{ |
||||
|
if (base == 0.0){ |
||||
|
return -1.0; |
||||
|
} |
||||
|
return (1.0 / p((exp*-1), base)); |
||||
|
} |
||||
|
}else if(base > 0.0){ |
||||
|
if(exp>=0.0){ |
||||
|
return exponential(exp*logN(base, 0.00000001)); |
||||
|
} |
||||
|
else{ |
||||
|
if (base == 0.0){ |
||||
|
return -1.0; |
||||
|
} |
||||
|
return (1.0 / exponential((-1*exp)*logN(base, 0.00000001))); |
||||
|
} |
||||
|
} |
||||
|
return -1.0; |
||||
|
} |
||||
|
|
||||
|
unsigned long long fac(int x){ |
||||
|
unsigned long long prod = 1; |
||||
|
if(x==0) return 1; |
||||
|
for (int i = 1; i <= x; i++){ |
||||
|
if (prod > ULLONG_MAX / i){ |
||||
|
break; |
||||
|
} |
||||
|
prod*=i; |
||||
|
} |
||||
|
return prod; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
double exponential(double x){ |
||||
|
double sum = 0.0; |
||||
|
for(int i = 0; i<=21; i++){ |
||||
|
sum += (1.0/fac(i)*(powerD(i,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; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#ifndef EXPONENT_H |
||||
|
#define EXPONENT_H |
||||
|
|
||||
|
double p(double exp, double base); |
||||
|
double powerD(double exp, double base); |
||||
|
double exponential(double x); |
||||
|
double logN(double x, double eps); |
||||
|
|
||||
|
#endif // exponent.h |
@ -0,0 +1,150 @@ |
|||||
|
#ifdef TEST |
||||
|
|
||||
|
#include "unity.h" |
||||
|
|
||||
|
#include "exponent.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void test_DoubleBase_ForPositiveExponent(void){ |
||||
|
int r1, r2, r3; |
||||
|
|
||||
|
r1 = p(2.0, -2.0); |
||||
|
r2 = p(3.0, -3.0); |
||||
|
r3 = p(4.0, 5.0); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL_INT(4.0, r1); |
||||
|
TEST_ASSERT_EQUAL_INT(-27.0, r2); |
||||
|
TEST_ASSERT_EQUAL_INT(625.0, r3); |
||||
|
} |
||||
|
|
||||
|
void test_DoubleBase_ForNegativeExponent(void){ |
||||
|
float r1, r2, r3; |
||||
|
|
||||
|
r1 = powerD(-1.0, 2.0); |
||||
|
r2 = powerD(-3.0, -3.0); |
||||
|
r3 = powerD(-2.0, -2.0); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL_FLOAT(0.5, r1); |
||||
|
TEST_ASSERT_EQUAL_FLOAT(-0.0370370373, r2); |
||||
|
TEST_ASSERT_EQUAL_FLOAT(0.25, r3); |
||||
|
} |
||||
|
|
||||
|
void test_DoubleBase_for_positive_decimal_exponent(void){ |
||||
|
float r1, r2, r3; |
||||
|
|
||||
|
r1 = powerD(0.45, 3.0); |
||||
|
r2 = powerD(0.5, 9.0); |
||||
|
r3 = powerD(0.5, 2.0); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.639474, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 3.0, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.414213, r3); |
||||
|
} |
||||
|
|
||||
|
void test_DoubleDecimalBase_for_positive_decimal_exponent(void){ |
||||
|
float r1, r2, r3; |
||||
|
|
||||
|
r1 = powerD(0.31, 0.413); |
||||
|
r2 = powerD(0.5, 3.13432); |
||||
|
r3 = powerD(0.124, 10.1231); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.760229, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.770401, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.332474, r3); |
||||
|
} |
||||
|
|
||||
|
void test_DoubleBase_for_negative_decimal_exponent(void){ |
||||
|
float r1, r2, r3; |
||||
|
|
||||
|
r1 = powerD(-0.125, 3.0); |
||||
|
r2 = powerD(-0.5, 2.0); |
||||
|
r3 = powerD(-0.12923, 10.0); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.871685, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.707106, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.742625, r3); |
||||
|
} |
||||
|
|
||||
|
void test_DoubleDecimalBase_for_negative_decimal_exponent(void){ |
||||
|
float r1, r2, r3; |
||||
|
|
||||
|
r1 = powerD(-0.5, 6.2315); |
||||
|
r2 = powerD(-0.1937, 9.2309); |
||||
|
r3 = powerD(-2.2145, 22.9983); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.400593, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.650177, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.000964, r3); |
||||
|
} |
||||
|
|
||||
|
void test_exponent_edge_case(void){ |
||||
|
float r1, r2, r3, r4, r5; |
||||
|
|
||||
|
r1 = powerD(0, 2); |
||||
|
r2 = powerD(0, 0); |
||||
|
r3 = powerD(2, 0); |
||||
|
r4 = powerD(-3, 0); |
||||
|
r5 = powerD(0.5, -3); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.0, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 1.0, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 0.0, r3); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, -1.0, r4); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, -1.0, r5); |
||||
|
} |
||||
|
|
||||
|
void test_Exponent_with_positive_number(void){ |
||||
|
double r1, r2, r3; |
||||
|
|
||||
|
r1 = exponential(0.0); |
||||
|
r2 = exponential(1.0); |
||||
|
r3 = exponential(2.0); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL_DOUBLE(1.0, r1); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 2.718282, r2); |
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.0001, 7.389056, r3); |
||||
|
} |
||||
|
|
||||
|
void test_Exponent_with_negative_number(void){ |
||||
|
double r1, r2, r3; |
||||
|
|
||||
|
r1 = exponential(-1.0); |
||||
|
r2 = exponential(-2.0); |
||||
|
|
||||
|
TEST_ASSERT_DOUBLE_WITHIN(0.000001, 0.367879, r1); |
||||
|
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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue