/*****************************************************************************
 * $LastChangedDate: 2010-10-23 18:22:39 -0400 (Sat, 23 Oct 2010) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Weakly-deprecated math functions.  See math/funcs.hh.
 * REMINDERS: Consider using MATH_EXCEPTION() instead of ASSERT().
 *//*
 * LEGAL:   COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef MATH_FUNCS_DEPRECATED_HH
#define MATH_FUNCS_DEPRECATED_HH 1

#include "math/funcs_debug.hh"
#include "math/funcs.hh"

namespace math {

////////////////////////////////////////////////////////////////////////////////
///////////////////////////  C O M P A R I S O N  //////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/*****************************************************************************
 * @return True if two fp values are approximately equal.
 * This variant has an arg for how many fractional digits to compare.
 * NOTE: Will malfunction if arg is NaN/Infinity.
 *       Increasing fractionalDigits will increase miscompares.
 *       Trying to compare fp values more-and-more precisely is doomed to fail
 *       because fp values are inherently approximate.
 *----------------------------------------------------------------------------
 * This was deprecated because increasing fractionalDigits beyond 3
 * had a tendency to miscompare numbers that were nearly equal.
 * So the faster FP_EQ() variant is better than this
 * if this has to be restricted to fractionalDigits <= 3 
 *****************************************************************************/
INLINE bool
FP_EQ( const fpx a, const fpx b, const uint fractionalDigits )
{
ASSERT( not (IfNan(a) or IfNan(b)) );
ASSERT( fractionalDigits < 20 );  // uint64 has 20 decimal digits

    // Try subtracting them.
    fpx diff = std::abs( a - b );

    // They could be approximately equal if the difference is a fraction.
    if ( diff < 1.0f )
    {
        // Shift fractional digits into integral part.
        diff = diff * std::pow( fpx(10.0f), fpx(fractionalDigits) );  // needs extended precision here

        // Truncate the integral part.  Return false if integral part isn't 0 (miscompare).
        // FP_EQ( 1.234, 1.236, 2 ) --> diff=0.002 --> shift:=0.2 --> trunc:0  equal
        // FP_EQ( 1.234, 1.236, 3 ) --> diff=0.002 --> shift:=2.0 --> trunc:2  not equal
        return uint64(diff) == 0;
    }
    else // diff >= 1.0f
    {
        return false;
    }
}

} // namespace math

#endif // MATH_FUNCS_DEPRECATED_HH
