diff --git a/docs/tostring.md b/docs/tostring.md
index 77322dc6..549f8aed 100644
--- a/docs/tostring.md
+++ b/docs/tostring.md
@@ -7,6 +7,8 @@
[Catch::is_range specialisation](#catchis_range-specialisation)
[Exceptions](#exceptions)
[Enums](#enums)
+[Floating point precision](#floating-point-precision)
+
Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
@@ -104,6 +106,22 @@ TEST_CASE() {
}
```
+## Floating point precision
+
+Catch provides a built-in `StringMaker` specialization for both `float`
+`double`. By default, it uses what we think is a reasonable precision,
+but you can customize it by modifying the `precision` static variable
+inside the `StringMaker` specialization, like so:
+
+```cpp
+ Catch::StringMaker::precision = 15;
+ const float testFloat1 = 1.12345678901234567899f;
+ const float testFloat2 = 1.12345678991234567899f;
+ REQUIRE(testFloat1 == testFloat2);
+```
+
+This assertion will fail and print out the `testFloat1` and `testFloat2`
+to 15 decimal places.
---
diff --git a/include/internal/catch_tostring.cpp b/include/internal/catch_tostring.cpp
index b857d3fb..f59676e7 100644
--- a/include/internal/catch_tostring.cpp
+++ b/include/internal/catch_tostring.cpp
@@ -234,11 +234,16 @@ std::string StringMaker::convert(std::nullptr_t) {
return "nullptr";
}
+int StringMaker::precision = 5;
+
std::string StringMaker::convert(float value) {
- return fpToString(value, 5) + 'f';
+ return fpToString(value, precision) + 'f';
}
+
+int StringMaker::precision = 10;
+
std::string StringMaker::convert(double value) {
- return fpToString(value, 10);
+ return fpToString(value, precision);
}
std::string ratio_string::symbol() { return "a"; }
diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h
index 52634a8c..cb248ea9 100644
--- a/include/internal/catch_tostring.h
+++ b/include/internal/catch_tostring.h
@@ -261,10 +261,13 @@ namespace Catch {
template<>
struct StringMaker {
static std::string convert(float value);
+ static int precision;
};
+
template<>
struct StringMaker {
static std::string convert(double value);
+ static int precision;
};
template
diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt
index 259954e4..8447e839 100644
--- a/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -859,6 +859,10 @@ Condition.tests.cpp:: passed: cpc != 0 for: 0x != 0
Condition.tests.cpp:: passed: returnsNull() == 0 for: {null string} == 0
Condition.tests.cpp:: passed: returnsConstNull() == 0 for: {null string} == 0
Condition.tests.cpp:: passed: 0 != p for: 0 != 0x
+ToStringGeneral.tests.cpp:: passed: str1.size() == 3 + 5 for: 8 == 8
+ToStringGeneral.tests.cpp:: passed: str2.size() == 3 + 10 for: 13 == 13
+ToStringGeneral.tests.cpp:: passed: str1.size() == 2 + 5 for: 7 == 7
+ToStringGeneral.tests.cpp:: passed: str2.size() == 2 + 15 for: 17 == 17
Matchers.tests.cpp:: passed: "foo", Predicate([] (const char* const&) { return true; }) for: "foo" matches undescribed predicate
CmdLine.tests.cpp:: passed: result for: {?}
CmdLine.tests.cpp:: passed: config.processName == "" for: "" == ""
diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt
index 0a4de923..aa991bd4 100644
--- a/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/projects/SelfTest/Baselines/console.std.approved.txt
@@ -1299,6 +1299,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
-test cases: 266 | 199 passed | 63 failed | 4 failed as expected
-assertions: 1449 | 1304 passed | 124 failed | 21 failed as expected
+test cases: 267 | 200 passed | 63 failed | 4 failed as expected
+assertions: 1453 | 1308 passed | 124 failed | 21 failed as expected
diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt
index 2b998afc..e13a6c23 100644
--- a/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -6192,6 +6192,40 @@ Condition.tests.cpp:: PASSED:
with expansion:
0 != 0x
+-------------------------------------------------------------------------------
+Precision of floating point stringification can be set
+ Floats
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:
+...............................................................................
+
+ToStringGeneral.tests.cpp:: PASSED:
+ CHECK( str1.size() == 3 + 5 )
+with expansion:
+ 8 == 8
+
+ToStringGeneral.tests.cpp:: PASSED:
+ REQUIRE( str2.size() == 3 + 10 )
+with expansion:
+ 13 == 13
+
+-------------------------------------------------------------------------------
+Precision of floating point stringification can be set
+ Double
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:
+...............................................................................
+
+ToStringGeneral.tests.cpp:: PASSED:
+ CHECK( str1.size() == 2 + 5 )
+with expansion:
+ 7 == 7
+
+ToStringGeneral.tests.cpp:: PASSED:
+ REQUIRE( str2.size() == 2 + 15 )
+with expansion:
+ 17 == 17
+
-------------------------------------------------------------------------------
Predicate matcher can accept const char*
-------------------------------------------------------------------------------
@@ -11389,6 +11423,6 @@ Misc.tests.cpp:
Misc.tests.cpp:: PASSED:
===============================================================================
-test cases: 266 | 183 passed | 79 failed | 4 failed as expected
-assertions: 1466 | 1304 passed | 141 failed | 21 failed as expected
+test cases: 267 | 184 passed | 79 failed | 4 failed as expected
+assertions: 1470 | 1308 passed | 141 failed | 21 failed as expected
diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt
index 7f4b43db..a7b77533 100644
--- a/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
-
+
@@ -574,6 +574,8 @@ Message.tests.cpp:
+
+
diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt
index fa078ac8..fcd6ff13 100644
--- a/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -7778,6 +7778,47 @@ Nor would this
+
+
+
+
+ str1.size() == 3 + 5
+
+
+ 8 == 8
+
+
+
+
+ str2.size() == 3 + 10
+
+
+ 13 == 13
+
+
+
+
+
+
+
+ str1.size() == 2 + 5
+
+
+ 7 == 7
+
+
+
+
+ str2.size() == 2 + 15
+
+
+ 17 == 17
+
+
+
+
+
+
@@ -13728,7 +13769,7 @@ loose text artifact
-
+
-
+
diff --git a/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp b/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
index 09ac3045..69d6320d 100644
--- a/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
+++ b/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
@@ -128,6 +128,40 @@ TEST_CASE("String views are stringified like other strings", "[toString][approva
#endif
+TEST_CASE("Precision of floating point stringification can be set", "[toString][floatingPoint]") {
+ SECTION("Floats") {
+ using sm = Catch::StringMaker;
+ const auto oldPrecision = sm::precision;
+
+ const float testFloat = 1.12345678901234567899f;
+ auto str1 = sm::convert(testFloat);
+ sm::precision = 5;
+ // "1." prefix = 2 chars, f suffix is another char
+ CHECK(str1.size() == 3 + 5);
+
+ sm::precision = 10;
+ auto str2 = sm::convert(testFloat);
+ REQUIRE(str2.size() == 3 + 10);
+ sm::precision = oldPrecision;
+ }
+ SECTION("Double") {
+ using sm = Catch::StringMaker;
+ const auto oldPrecision = sm::precision;
+
+ const double testDouble = 1.123456789012345678901234567899;
+ sm::precision = 5;
+ auto str1 = sm::convert(testDouble);
+ // "1." prefix = 2 chars
+ CHECK(str1.size() == 2 + 5);
+
+ sm::precision = 15;
+ auto str2 = sm::convert(testDouble);
+ REQUIRE(str2.size() == 2 + 15);
+
+ sm::precision = oldPrecision;
+ }
+}
+
namespace {
struct WhatException : std::exception {