Gaudi Framework, version v23r1

Home   Generated: Wed Feb 29 2012
Classes | Functions

Gaudi::Math Namespace Reference

Classes

class  Lomont< float >
 the specialization for float numbers More...
class  Lomont< double >
 the specialization for double numbers More...

Functions

GAUDI_API bool lomont_compare_float (const float af, const float bf, const unsigned short maxULPs)
 equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP).
GAUDI_API bool lomont_compare_double (const double af, const double bf, const unsigned int maxULPs)
 equality comparison of double numbers using as the metric the maximal number of Units in the Last Place (ULP).
GAUDI_API float next_float (const float af, const short ulps)
 Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".
GAUDI_API double next_double (const double af, const short ulps)
 Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".

Function Documentation

bool Gaudi::Math::lomont_compare_double ( const double  af,
const double  bf,
const unsigned int  maxULPs 
)

equality comparison of double numbers using as the metric the maximal number of Units in the Last Place (ULP).

It is a slightly modified version of very efficient implementation of the initial Bruce Dawson's algorithm by Chris Lomont.

See also:
www.lomont.org
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

C.Lomont claims the algorithm is factor 2-10 more efficient with respect to classical Knuth's algorithm for comparison of the floating number using the relative precision.

The effective relative difference depends on the choice of maxULPS:

  • For the case of maxULPs=1, (of course it is totally unphysical case!!!) the effective relative precision r = |a-b|/(|a|+|b|)is ~6e-16 for |a|,|b|>1.e-304, and then it quickly goes to ~1
  const double a = ... ;
  const double b = ... ;

  const bool equal = Gaudi::Math::lomont_compare_double ( a , b ) ;
Parameters:
afthe first number
bfthe second number
maxULPsthe maximal metric deviation in the terms of maximal number of units in the last place
Author:
Vanya BELYAEV Ivan.Belyaev@nikhef.nl
Date:
2008-11-08

the final check

Definition at line 291 of file Lomont.cpp.

{
  // ==========================================================================
  BOOST_STATIC_ASSERT( std::numeric_limits<double>  ::is_specialized &&
                       std::numeric_limits<Long>    ::is_specialized && 
                       std::numeric_limits<ULong>   ::is_specialized &&
                       boost::integer_traits<ULong> ::is_specialized &&
                       boost::integer_traits<Long>  ::is_specialized &&
                       sizeof(double)==sizeof(Long)                  && 
                       sizeof(double)==sizeof(ULong)                 &&
                       64 == std::numeric_limits<ULong>::digits      ) ;
  // ==========================================================================
  Cast_D caster ;
  
  //Long ai = *reinterpret_cast<const Long*>( &af ) ;
  //Long bi = *reinterpret_cast<const Long*>( &bf ) ;
  Long ai = caster.d2l ( af ) ;
  Long bi = caster.d2l ( bf ) ;
  
  Long test = (((ULong)(ai^bi))>>63)-1;
  
  // assert ( (0==test) || ( boost::integer_traits<ULong>::const_max == test ) ) ;
  
  Long diff = ((( boost::integer_traits<Long>::const_min - ai ) & (~test)) | ( ai& test )) - bi ;
  
  Long maxDiff_ = maxULPs ;
  
  Long v1 = maxDiff_ + diff ;
  Long v2 = maxDiff_ - diff ;
  
  return 0<=(v1|v2) ;
}
bool Gaudi::Math::lomont_compare_float ( const float  af,
const float  bf,
const unsigned short  maxULPs 
)

equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP).

It is a slightly modified version of very efficient implementation of the initial Bruce Dawson's algorithm by Chris Lomont.

See also:
www.lomont.org
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

C.Lomont claims the algorithm is factor 2-10 more efficient with respect to classical Knuth's algorithm for comparison of the floating number using the relative precision.

The effective relative difference depends on the choice of maxULPS:

  • For the case of maxULPs=1, (of course it is totally unphysical case!!!) the effective relative precision r = |a-b|/(|a|+|b|)is between 3.5e-8 and 5.5e-8 for |a|,|b|>1.e-37, and then it quickly goes to ~1
  • For the case of maxULPS=10 the effective relative precision is between 3e-8 and 6e-7 for |a|,|b|>1.e-37, and then it quickly goes to ~1
  • For the case of maxULPS=100 the effective relative precision is around ~6e-6 for |a|,|b|>1.e-37, and then it quickly goes to ~1
  • For the case of maxULPS=1000 the effective relative precision is around ~6e-5 for |a|,|b|>1.e-37, and then it quickly goes to ~1
  const float a = ... ;
  const float b = ... ;

  const bool equal = Gaudi::Math::lomont_compare_float ( a , b ) ;
Parameters:
afthe first number
bfthe second number
maxULPsthe maximal metric deviation in the terms of maximal number of units in the last place
Author:
Vanya BELYAEV Ivan.Belyaev@nikhef.nl
Date:
2008-11-08

Definition at line 195 of file Lomont.cpp.

{
  // ==========================================================================
  // prerequisites:
  BOOST_STATIC_ASSERT( std::numeric_limits<float>          ::is_specialized &&
                       boost::integer_traits<int>          ::is_specialized && 
                       boost::integer_traits<unsigned int> ::is_specialized &&
                       sizeof(float)==sizeof(int)                           && 
                       sizeof(float)==sizeof(unsigned int)                  &&
                       32 == boost::integer_traits<unsigned int>::digits    ) ;
  // ==========================================================================
  
  Cast_F caster ;
  
  //int ai = *reinterpret_cast<const int*>( &af ) ;
  //int bi = *reinterpret_cast<const int*>( &bf ) ;
  int ai = caster.f2i ( af ) ;
  int bi = caster.f2i ( bf ) ;
  
  int test = (((unsigned int)(ai^bi))>>31)-1;
  
  // assert ( (0==test) || ( boost::integer_traits<unsigned int>::const_max == test ) ) ;
  
  int diff = ((( boost::integer_traits<int>::const_min - ai ) & (~test)) | ( ai& test )) - bi ;
  
  int maxDiff_ = maxULPs ;
  
  int v1 = maxDiff_ + diff ;
  int v2 = maxDiff_ - diff ;
  
  return 0<=(v1|v2) ;
}
double Gaudi::Math::next_double ( const double  af,
const short  ulps 
)

Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".

For ulps=1, it is just next float number, for ulps=-1 is is the previous one.

This routine is very convenient to test the parameter maxULPS for the routine Gaudi::Math::lomont_compare_double

See also:
Gaudi::Math::lomont_compare_double
Parameters:
afthe reference number
ulpsthe bias
Returns:
the biased float number (on distance "ulps")
Author:
Vanya BELYAEV Ivan.Belyaev@nikhef.nl
Date:
2008-11-08

the final check

Definition at line 344 of file Lomont.cpp.

{
  // ==========================================================================
  BOOST_STATIC_ASSERT( std::numeric_limits<double> ::is_specialized &&
                       std::numeric_limits<Long>   ::is_specialized && 
                       sizeof(double)==sizeof(Long) ) ;
  // ==========================================================================
  Cast_D caster ;
  
  //Long al = *reinterpret_cast<const Long*>( &ad ) ;
  Long al = caster.d2l ( ad ) ;
  al += ulps ;
  //return *reinterpret_cast<double*>(&al) ;
  return caster.l2d ( al ) ;
}
float Gaudi::Math::next_float ( const float  af,
const short  ulps 
)

Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".

For ulps=1, it is just next float number, for ulps=-1 is is the previous one.

This routine is very convenient to test the parameter maxULPS for the routine Gaudi::Math::lomont_compare_float

See also:
Gaudi:Math::lomont_compare_float
Parameters:
afthe reference number
ulpsthe bias
Returns:
the biased float number (on distance "ulps")
Author:
Vanya BELYAEV Ivan.Belyaev@nikhef.nl
Date:
2008-11-08

the final check

Definition at line 247 of file Lomont.cpp.

{
  BOOST_STATIC_ASSERT( std::numeric_limits<float> ::is_specialized &&
                       std::numeric_limits<int>   ::is_specialized && 
                       sizeof(float)==sizeof(int) ) ;
  // ==========================================================================
  Cast_F caster ;
  
  // int ai = *reinterpret_cast<const int*>( &af ) ;
  int ai = caster.f2i ( af ) ;
  ai += ulps ;
  // return *reinterpret_cast<float*>(&ai) ;
  return   caster.i2f ( ai ) ;
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 29 2012 15:31:28 for Gaudi Framework, version v23r1 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004