mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-16 18:52:25 +01:00
d2d418a9cb
It checks Knuth's _close enough with tolerance_ relationship, that is `|lhs - rhs| <= epsilon * max(|lhs|, |rhs|)`, rather then the _very close with tolerance_ relationship that can be written down as `|lhs - rhs| <= epsilon * min(|lhs|, |rhs|)`. This is because it is the more common model around the internet, and as such is likely to be less surprising to the users. In the future we might want to provide the other model as well. Closes #1746
71 lines
2.7 KiB
C++
71 lines
2.7 KiB
C++
/*
|
|
* Created by Martin on 07/11/2017.
|
|
*
|
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|
|
#define TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|
|
|
|
#include "catch_matchers.h"
|
|
|
|
namespace Catch {
|
|
namespace Matchers {
|
|
|
|
namespace Floating {
|
|
|
|
enum class FloatingPointKind : uint8_t;
|
|
|
|
struct WithinAbsMatcher : MatcherBase<double> {
|
|
WithinAbsMatcher(double target, double margin);
|
|
bool match(double const& matchee) const override;
|
|
std::string describe() const override;
|
|
private:
|
|
double m_target;
|
|
double m_margin;
|
|
};
|
|
|
|
struct WithinUlpsMatcher : MatcherBase<double> {
|
|
WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
|
|
bool match(double const& matchee) const override;
|
|
std::string describe() const override;
|
|
private:
|
|
double m_target;
|
|
uint64_t m_ulps;
|
|
FloatingPointKind m_type;
|
|
};
|
|
|
|
// Given IEEE-754 format for floats and doubles, we can assume
|
|
// that float -> double promotion is lossless. Given this, we can
|
|
// assume that if we do the standard relative comparison of
|
|
// |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
|
|
// the same result if we do this for floats, as if we do this for
|
|
// doubles that were promoted from floats.
|
|
struct WithinRelMatcher : MatcherBase<double> {
|
|
WithinRelMatcher(double target, double epsilon);
|
|
bool match(double const& matchee) const override;
|
|
std::string describe() const override;
|
|
private:
|
|
double m_target;
|
|
double m_epsilon;
|
|
};
|
|
|
|
} // namespace Floating
|
|
|
|
// The following functions create the actual matcher objects.
|
|
// This allows the types to be inferred
|
|
Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
|
|
Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
|
|
Floating::WithinAbsMatcher WithinAbs(double target, double margin);
|
|
Floating::WithinRelMatcher WithinRel(double target, double eps);
|
|
// defaults epsilon to 100*numeric_limits<double>::epsilon()
|
|
Floating::WithinRelMatcher WithinRel(double target);
|
|
Floating::WithinRelMatcher WithinRel(float target, float eps);
|
|
// defaults epsilon to 100*numeric_limits<float>::epsilon()
|
|
Floating::WithinRelMatcher WithinRel(float target);
|
|
|
|
} // namespace Matchers
|
|
} // namespace Catch
|
|
|
|
#endif // TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|