dune-common 2.9.0
|
Namespaces | |
namespace | Dune::FloatCmp |
Classes | |
struct | Dune::FloatCmp::EpsilonType< T > |
Mapping of value type to epsilon type. More... | |
struct | Dune::FloatCmp::EpsilonType< std::vector< T, A > > |
Specialization of EpsilonType for std::vector. More... | |
struct | Dune::FloatCmp::EpsilonType< FieldVector< T, n > > |
Specialization of EpsilonType for Dune::FieldVector. More... | |
struct | Dune::FloatCmp::DefaultEpsilon< T, style > |
mapping from a value type and a compare style to a default epsilon More... | |
class | Dune::FloatCmpOps< T, cstyle_, rstyle_ > |
Class encapsulating a default epsilon. More... | |
Enumerations | |
enum | Dune::FloatCmp::CmpStyle { Dune::FloatCmp::relativeWeak , Dune::FloatCmp::relativeStrong , Dune::FloatCmp::absolute , Dune::FloatCmp::defaultCmpStyle = relativeWeak } |
enum | Dune::FloatCmp::RoundingStyle { Dune::FloatCmp::towardZero , Dune::FloatCmp::towardInf , Dune::FloatCmp::downward , Dune::FloatCmp::upward , Dune::FloatCmp::defaultRoundingStyle = towardZero } |
Functions | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::eq (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test for equality using epsilon | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::ne (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test for inequality using epsilon | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::gt (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test if first greater than second | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::lt (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test if first lesser than second | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::ge (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test if first greater or equal second | |
template<class T , CmpStyle style> | |
bool | Dune::FloatCmp::le (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value()) |
test if first lesser or equal second | |
template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle> | |
I | Dune::FloatCmp::round (const T &val, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, cstyle >::value()) |
round using epsilon | |
template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle> | |
I | Dune::FloatCmp::trunc (const T &val, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, cstyle >::value()) |
truncate using epsilon | |
When comparing floating point numbers for equality, one often faces the problem that floating point operations are not always exact. For example on i386 the expression
evaluates to
which is false. One solution is to compare approximately, using an epsilon which says how much deviation to accept.
The most straightforward way of comparing is using an absolute epsilon. This means comparison for equality is replaced by
This has a severe disadvantage: if you have an epsilon like 1e-10 but first and second are of the magnitude 1e-15 everything will compare equal which is certainly not what you want. This can be overcome by selecting an appropriate epsilon. Nevertheless this method of comparing is not recommended in general, and we will present a more robus method in the next paragraph.
There is another way of comparing approximately, using a relative epsilon which is then scaled with first:
Of course the comparison should be symmetric in first and second so we cannot arbitrarily select either first or second to scale epsilon. The are two symmetric variants, relative_weak
and relative_strong
Both variants are good, but in practice the relative_weak variant is preferred. This is also the default variant.
There is a completely different way of comparing floats. Instead of giving an epsilon, the programmer states how many representable value are allowed between first and second. See the "Comparing using integers" section in http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm for more about that.
To do the comparison, you can use the free functions eq(), ne(), gt(), lt(), ge() and le() from the namespace Dune::FloatCmp. They take the values to compare and optionally an epsilon, which defaults to 8 times the machine epsilon (the difference between 1.0 and the smallest representable value > 1.0) for relative comparisons, or simply 1e-6 for absolute comparisons. The compare style can be given as an optional second template parameter and defaults to relative_weak.
You can also use the class Dune::FloatCmpOps which has eq(), ne(), gt(), lt(), ge() and le() as member functions. In this case the class encapsulates the epsilon and the comparison style (again the defaults from the previous paragraph apply). This may be more convenient if you write your own class utilizing floating point comparisons, and you want the user of you class to specify epsilon and compare style.
bool Dune::FloatCmp::eq | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test for equality using epsilon
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of equals operation |
second | right operand of equals operation |
epsilon | The epsilon to use in the comparison |
bool Dune::FloatCmp::ge | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test if first greater or equal second
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of greater-or-equals operation |
second | right operand of greater-or-equals operation |
epsilon | The epsilon to use in the comparison |
this is like first > second, but the region that compares equal with an epsilon is also included
bool Dune::FloatCmp::gt | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test if first greater than second
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of greater-than operation |
second | right operand of greater-than operation |
epsilon | The epsilon to use in the comparison |
this is like first > second but the region that compares equal with an epsilon is excluded
bool Dune::FloatCmp::le | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test if first lesser or equal second
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of less-or-equals operation |
second | right operand of less-or-equals operation |
epsilon | The epsilon to use in the comparison |
this is like first < second, but the region that compares equal with an epsilon is also included
bool Dune::FloatCmp::lt | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test if first lesser than second
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of less-than operation |
second | right operand of less-than operation |
epsilon | The epsilon to use in the comparison |
this is like first < second, but the region that compares equal with an epsilon is excluded
bool Dune::FloatCmp::ne | ( | const T & | first, |
const T & | second, | ||
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, style >::value() |
||
) |
test for inequality using epsilon
T | Type of the values to compare |
style | How to compare. This defaults to defaultCmpStyle. |
first | left operand of not-equal operation |
second | right operand of not-equal operation |
epsilon | The epsilon to use in the comparison |
I Dune::FloatCmp::round | ( | const T & | val, |
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, cstyle >::value() |
||
) |
round using epsilon
I | The integral type to round to |
T | Type of the value to round |
cstyle | How to compare. This defaults to defaultCmpStyle. |
rstyle | How to round. This defaults to defaultRoundingStyle. |
val | The value to round |
epsilon | The epsilon to use in comparisons |
Round according to rstyle. If val is already near the mean of two adjacent integers in terms of epsilon, the result will be the rounded mean.
I Dune::FloatCmp::trunc | ( | const T & | val, |
typename EpsilonType< T >::Type | epsilon = DefaultEpsilon< T, cstyle >::value() |
||
) |
truncate using epsilon
I | The integral type to truncate to |
T | Type of the value to truncate |
cstyle | How to compare. This defaults to defaultCmpStyle. |
rstyle | How to truncate. This defaults to defaultRoundingStyle. |
val | The value to truncate |
epsilon | The epsilon to use in comparisons |
Truncate according to rstyle. If val is already near an integer in terms of epsilon, the result will be that integer instead of the real truncated value.