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