Allow changing the format of StringMaker<float> and StringMaker<double>

This commit is contained in:
Will Pazner 2021-04-29 14:51:06 -07:00
parent 2dc5a5f402
commit 14d0d46cd1
3 changed files with 19 additions and 5 deletions

View File

@ -127,6 +127,17 @@ inside the `StringMaker` specialization, like so:
This assertion will fail and print out the `testFloat1` and `testFloat2` This assertion will fail and print out the `testFloat1` and `testFloat2`
to 15 decimal places. to 15 decimal places.
`StringMaker<float>` and `StringMaker<double>` default to using fixed output,
but can be set to use scientific notation by modifying the `format` static
variable:
```cpp
Catch::StringMaker<float>::format = std::scientific;
const float testFloat1 = 1e-5f;
const float testFloat2 = 1e-6f;
REQUIRE(testFloat1 == testFloat2);
```
--- ---
[Home](Readme.md#top) [Home](Readme.md#top)

View File

@ -42,14 +42,14 @@ namespace Detail {
}; };
template<typename T> template<typename T>
std::string fpToString(T value, int precision) { std::string fpToString(T value, int precision, std::ios_base &(*format)(std::ios_base &)) {
if (Catch::isnan(value)) { if (Catch::isnan(value)) {
return "nan"; return "nan";
} }
ReusableStringStream rss; ReusableStringStream rss;
rss << std::setprecision(precision) rss << std::setprecision(precision)
<< std::fixed << format
<< value; << value;
std::string d = rss.str(); std::string d = rss.str();
std::size_t i = d.find_last_not_of('0'); std::size_t i = d.find_last_not_of('0');
@ -225,15 +225,17 @@ std::string StringMaker<unsigned char>::convert(unsigned char c) {
} }
int StringMaker<float>::precision = 5; int StringMaker<float>::precision = 5;
std::ios_base &(*StringMaker<float>::format)(std::ios_base &) = std::fixed;
std::string StringMaker<float>::convert(float value) { std::string StringMaker<float>::convert(float value) {
return Detail::fpToString(value, precision) + 'f'; return Detail::fpToString(value, precision, format) + 'f';
} }
int StringMaker<double>::precision = 10; int StringMaker<double>::precision = 10;
std::ios_base &(*StringMaker<double>::format)(std::ios_base &) = std::fixed;
std::string StringMaker<double>::convert(double value) { std::string StringMaker<double>::convert(double value) {
return Detail::fpToString(value, precision); return Detail::fpToString(value, precision, format);
} }
} // end namespace Catch } // end namespace Catch
@ -241,4 +243,3 @@ std::string StringMaker<double>::convert(double value) {
#if defined(__clang__) #if defined(__clang__)
# pragma clang diagnostic pop # pragma clang diagnostic pop
#endif #endif

View File

@ -271,12 +271,14 @@ namespace Catch {
struct StringMaker<float> { struct StringMaker<float> {
static std::string convert(float value); static std::string convert(float value);
static int precision; static int precision;
static std::ios_base &(*format)(std::ios_base &);
}; };
template<> template<>
struct StringMaker<double> { struct StringMaker<double> {
static std::string convert(double value); static std::string convert(double value);
static int precision; static int precision;
static std::ios_base &(*format)(std::ios_base &);
}; };
template <typename T> template <typename T>