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 */ | ||||