|
Gaudi Framework, version v21r7 |
| Home | Generated: 22 Jan 2010 |
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". | |
| 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.
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
The effective relative difference depends on the choice of maxULPS:
const double a = ... ; const double b = ... ; const bool equal = Gaudi::Math::lomont_compare_double ( a , b ) ;
| af | the first number | |
| bf | the second number | |
| maxULPs | the maximal metric deviation in the terms of maximal number of units in the last place |
the final check
Definition at line 291 of file Lomont.cpp.
00294 { 00295 // ========================================================================== 00297 BOOST_STATIC_ASSERT( std::numeric_limits<double> ::is_specialized && 00298 std::numeric_limits<Long> ::is_specialized && 00299 std::numeric_limits<ULong> ::is_specialized && 00300 boost::integer_traits<ULong> ::is_specialized && 00301 boost::integer_traits<Long> ::is_specialized && 00302 sizeof(double)==sizeof(Long) && 00303 sizeof(double)==sizeof(ULong) && 00304 64 == std::numeric_limits<ULong>::digits ) ; 00305 // ========================================================================== 00306 Cast_D caster ; 00307 00308 //Long ai = *reinterpret_cast<const Long*>( &af ) ; 00309 //Long bi = *reinterpret_cast<const Long*>( &bf ) ; 00310 Long ai = caster.d2l ( af ) ; 00311 Long bi = caster.d2l ( bf ) ; 00312 00313 Long test = (((ULong)(ai^bi))>>63)-1; 00314 00315 // assert ( (0==test) || ( boost::integer_traits<ULong>::const_max == test ) ) ; 00316 00317 Long diff = ((( boost::integer_traits<Long>::const_min - ai ) & (~test)) | ( ai& test )) - bi ; 00318 00319 Long maxDiff_ = maxULPs ; 00320 00321 Long v1 = maxDiff_ + diff ; 00322 Long v2 = maxDiff_ - diff ; 00323 00324 return 0<=(v1|v2) ; 00325 }
| 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.
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
The effective relative difference depends on the choice of maxULPS:
const float a = ... ; const float b = ... ; const bool equal = Gaudi::Math::lomont_compare_float ( a , b ) ;
| af | the first number | |
| bf | the second number | |
| maxULPs | the maximal metric deviation in the terms of maximal number of units in the last place |
Definition at line 195 of file Lomont.cpp.
00198 { 00199 // ========================================================================== 00200 // prerequisites: 00201 BOOST_STATIC_ASSERT( std::numeric_limits<float> ::is_specialized && 00202 boost::integer_traits<int> ::is_specialized && 00203 boost::integer_traits<unsigned int> ::is_specialized && 00204 sizeof(float)==sizeof(int) && 00205 sizeof(float)==sizeof(unsigned int) && 00206 32 == boost::integer_traits<unsigned int>::digits ) ; 00207 // ========================================================================== 00208 00209 Cast_F caster ; 00210 00211 //int ai = *reinterpret_cast<const int*>( &af ) ; 00212 //int bi = *reinterpret_cast<const int*>( &bf ) ; 00213 int ai = caster.f2i ( af ) ; 00214 int bi = caster.f2i ( bf ) ; 00215 00216 int test = (((unsigned int)(ai^bi))>>31)-1; 00217 00218 // assert ( (0==test) || ( boost::integer_traits<unsigned int>::const_max == test ) ) ; 00219 00220 int diff = ((( boost::integer_traits<int>::const_min - ai ) & (~test)) | ( ai& test )) - bi ; 00221 00222 int maxDiff_ = maxULPs ; 00223 00224 int v1 = maxDiff_ + diff ; 00225 int v2 = maxDiff_ - diff ; 00226 00227 return 0<=(v1|v2) ; 00228 }
| 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
| af | the reference number | |
| ulps | the bias |
the final check
Definition at line 344 of file Lomont.cpp.
00345 { 00346 // ========================================================================== 00348 BOOST_STATIC_ASSERT( std::numeric_limits<double> ::is_specialized && 00349 std::numeric_limits<Long> ::is_specialized && 00350 sizeof(double)==sizeof(Long) ) ; 00351 // ========================================================================== 00352 Cast_D caster ; 00353 00354 //Long al = *reinterpret_cast<const Long*>( &ad ) ; 00355 Long al = caster.d2l ( ad ) ; 00356 al += ulps ; 00357 //return *reinterpret_cast<double*>(&al) ; 00358 return caster.l2d ( al ) ; 00359 }
| 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
| af | the reference number | |
| ulps | the bias |
the final check
Definition at line 247 of file Lomont.cpp.
00248 { 00250 BOOST_STATIC_ASSERT( std::numeric_limits<float> ::is_specialized && 00251 std::numeric_limits<int> ::is_specialized && 00252 sizeof(float)==sizeof(int) ) ; 00253 // ========================================================================== 00254 Cast_F caster ; 00255 00256 // int ai = *reinterpret_cast<const int*>( &af ) ; 00257 int ai = caster.f2i ( af ) ; 00258 ai += ulps ; 00259 // return *reinterpret_cast<float*>(&ai) ; 00260 return caster.i2f ( ai ) ; 00261 }