| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# 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:

  | 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

Author:
  Vanya BELYAEV Ivan.Belyaev@nikhef.nl

Date:
  2008-11-08

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.

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:

  | 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

Author:
  Vanya BELYAEV Ivan.Belyaev@nikhef.nl

Date:
  2008-11-08

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

See also:
  Gaudi::Math::lomont_compare_double

Parameters:

  | af | the reference number
  | ulps | the 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.

    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

See also:
  Gaudi:Math::lomont_compare_float

Parameters:

  | af | the reference number
  | ulps | the 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.

    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 }