// RationalApproximation.cpp
//---------------------------------------------------------------------------
#include "RationalApproximation.h"
#include <math.h>
#include <algorithm>
#include <limits>
//---------------------------------------------------------------------------
TRationalApproximation::TRationalApproximation()
: m_defaultTolerance(1e-6)
, m_numerator(0.0)
, m_denominator(0.0)
{
}
//---------------------------------------------------------------------------
void TRationalApproximation::Calculate(double value)
{
Calculate(value, m_defaultTolerance * fabs(value));
}
//---------------------------------------------------------------------------
void TRationalApproximation::Calculate(double value, double tolerance)
{
double x = value,
c11 = 1.0, c12 = 0.0,
c21 = 0.0, c22 = 1.0,
epsilonTolerance = std::numeric_limits<double>::epsilon()*fabs(value),
maxTolerance = std::max(tolerance, epsilonTolerance);
while(1)
{
double d = (x > 0) ? floor(x + 0.5) : -floor(-x + 0.5); // round(x)
x -= d;
double tmp_c12 = c12;
double tmp_c22 = c22;
c12 = c11;
c22 = c21;
c11 = c11 * d + tmp_c12;
c21 = c21 * d + tmp_c22;
if(x == 0 || fabs(c11/c21 - value) <= maxTolerance)
{
break;
}
x = 1.0 / x;
}
m_numerator = (c21 > 0) ? c11 : -c11;
m_denominator = fabs(c21);
}
//---------------------------------------------------------------------------
|