1 /*
2 * Created by Martin on 19/07/2017.
3 * Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
4 *
5 * Distributed under the Boost Software License, Version 1.0. (See accompanying
6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 */
8
9 #include "catch_approx.h"
10
11 #include <cmath>
12 #include <limits>
13
14 namespace {
15
16 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
17 // But without the subtraction to allow for INFINITY in comparison
marginComparison(double lhs,double rhs,double margin)18 bool marginComparison(double lhs, double rhs, double margin) {
19 return (lhs + margin >= rhs) && (rhs + margin >= lhs);
20 }
21
22 }
23
24 namespace Catch {
25 namespace Detail {
26
Approx(double value)27 Approx::Approx ( double value )
28 : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
29 m_margin( 0.0 ),
30 m_scale( 0.0 ),
31 m_value( value )
32 {}
33
custom()34 Approx Approx::custom() {
35 return Approx( 0 );
36 }
37
toString() const38 std::string Approx::toString() const {
39 ReusableStringStream rss;
40 rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
41 return rss.str();
42 }
43
equalityComparisonImpl(const double other) const44 bool Approx::equalityComparisonImpl(const double other) const {
45 // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
46 // Thanks to Richard Harris for his help refining the scaled margin value
47 return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
48 }
49
50 } // end namespace Detail
51
convert(Catch::Detail::Approx const & value)52 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
53 return value.toString();
54 }
55
56 } // end namespace Catch
57