catch_matchers_floating.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Created by Martin on 07/11/2017.
  3. *
  4. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #ifndef TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
  8. #define TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
  9. #include "catch_matchers.h"
  10. namespace Catch {
  11. namespace Matchers {
  12. namespace Floating {
  13. enum class FloatingPointKind : uint8_t;
  14. struct WithinAbsMatcher : MatcherBase<double> {
  15. WithinAbsMatcher(double target, double margin);
  16. bool match(double const& matchee) const override;
  17. std::string describe() const override;
  18. private:
  19. double m_target;
  20. double m_margin;
  21. };
  22. struct WithinUlpsMatcher : MatcherBase<double> {
  23. WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
  24. bool match(double const& matchee) const override;
  25. std::string describe() const override;
  26. private:
  27. double m_target;
  28. uint64_t m_ulps;
  29. FloatingPointKind m_type;
  30. };
  31. // Given IEEE-754 format for floats and doubles, we can assume
  32. // that float -> double promotion is lossless. Given this, we can
  33. // assume that if we do the standard relative comparison of
  34. // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
  35. // the same result if we do this for floats, as if we do this for
  36. // doubles that were promoted from floats.
  37. struct WithinRelMatcher : MatcherBase<double> {
  38. WithinRelMatcher(double target, double epsilon);
  39. bool match(double const& matchee) const override;
  40. std::string describe() const override;
  41. private:
  42. double m_target;
  43. double m_epsilon;
  44. };
  45. } // namespace Floating
  46. // The following functions create the actual matcher objects.
  47. // This allows the types to be inferred
  48. Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
  49. Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
  50. Floating::WithinAbsMatcher WithinAbs(double target, double margin);
  51. Floating::WithinRelMatcher WithinRel(double target, double eps);
  52. // defaults epsilon to 100*numeric_limits<double>::epsilon()
  53. Floating::WithinRelMatcher WithinRel(double target);
  54. Floating::WithinRelMatcher WithinRel(float target, float eps);
  55. // defaults epsilon to 100*numeric_limits<float>::epsilon()
  56. Floating::WithinRelMatcher WithinRel(float target);
  57. } // namespace Matchers
  58. } // namespace Catch
  59. #endif // TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED