and simplify the Remez code accordingly.legacy
| @@ -442,6 +442,19 @@ bool real::operator >=(real const &x) const | |||||
| return !(*this < x); | return !(*this < x); | ||||
| } | } | ||||
| bool real::operator !() const | |||||
| { | |||||
| return !(bool)*this; | |||||
| } | |||||
| real::operator bool() const | |||||
| { | |||||
| /* A real is "true" if it is non-zero (exponent is non-zero) AND | |||||
| * not NaN (exponent is not full bits OR higher order mantissa is zero) */ | |||||
| uint32_t exponent = m_signexp << 1; | |||||
| return exponent && (~exponent || m_mantissa[0] == 0); | |||||
| } | |||||
| real fres(real const &x) | real fres(real const &x) | ||||
| { | { | ||||
| if (!(x.m_signexp << 1)) | if (!(x.m_signexp << 1)) | ||||
| @@ -58,6 +58,9 @@ public: | |||||
| bool operator <=(real const &x) const; | bool operator <=(real const &x) const; | ||||
| bool operator >=(real const &x) const; | bool operator >=(real const &x) const; | ||||
| bool operator !() const; | |||||
| operator bool() const; | |||||
| friend real fabs(real const &x); | friend real fabs(real const &x); | ||||
| friend real fres(real const &x); | friend real fres(real const &x); | ||||
| @@ -21,30 +21,13 @@ using namespace lol; | |||||
| /* The order of the approximation we're looking for */ | /* The order of the approximation we're looking for */ | ||||
| static int const ORDER = 8; | static int const ORDER = 8; | ||||
| static real compute_pi() | |||||
| { | |||||
| /* Approximate Pi using Machin's formula: 16*atan(1/5)-4*atan(1/239) */ | |||||
| real sum = 0.0, x0 = 5.0, x1 = 239.0; | |||||
| real const m0 = -x0 * x0, m1 = -x1 * x1, r16 = 16.0, r4 = 4.0; | |||||
| /* Degree 240 is required for 512-bit mantissa precision */ | |||||
| for (int i = 1; i < 240; i += 2) | |||||
| { | |||||
| sum += r16 / (x0 * (real)i) - r4 / (x1 * (real)i); | |||||
| x0 *= m0; | |||||
| x1 *= m1; | |||||
| } | |||||
| return sum; | |||||
| } | |||||
| /* The function we want to approximate */ | /* The function we want to approximate */ | ||||
| static real myfun(real const &x) | static real myfun(real const &x) | ||||
| { | { | ||||
| static real const half_pi = compute_pi() * (real)0.5; | |||||
| static real const one = 1.0; | static real const one = 1.0; | ||||
| if (x == (real)0.0 || x == (real)-0.0) | |||||
| return half_pi; | |||||
| return sin(x * half_pi) / x; | |||||
| if (!x) | |||||
| return real::R_PI_2; | |||||
| return sin(x * real::R_PI_2) / x; | |||||
| //return cos(x) - one; | //return cos(x) - one; | ||||
| //return exp(x); | //return exp(x); | ||||
| } | } | ||||
| @@ -176,6 +176,23 @@ LOLUNIT_FIXTURE(RealTest) | |||||
| LOLUNIT_ASSERT_EQUAL((double)(a3 << 7), 0.0); | LOLUNIT_ASSERT_EQUAL((double)(a3 << 7), 0.0); | ||||
| LOLUNIT_ASSERT_EQUAL((double)(a3 << -7), 0.0); | LOLUNIT_ASSERT_EQUAL((double)(a3 << -7), 0.0); | ||||
| } | } | ||||
| LOLUNIT_TEST(Bool) | |||||
| { | |||||
| real a = 0.0; | |||||
| LOLUNIT_ASSERT(!a); | |||||
| a = -0.0; | |||||
| LOLUNIT_ASSERT(!a); | |||||
| a = 1234.0; | |||||
| LOLUNIT_ASSERT(a); | |||||
| LOLUNIT_ASSERT(!!a); | |||||
| a = -1234.0; | |||||
| LOLUNIT_ASSERT(a); | |||||
| LOLUNIT_ASSERT(!!a); | |||||
| } | |||||
| }; | }; | ||||
| } /* namespace lol */ | } /* namespace lol */ | ||||