Fix storing inf and NaN (#817)

This commit is contained in:
Anton Onishchenko
2020-02-15 03:03:21 +03:00
committed by GitHub
parent 29dcf92f87
commit de8253fcb0
2 changed files with 71 additions and 1 deletions

View File

@@ -8,10 +8,12 @@
#endif
#include <array>
#include <cmath>
#include <limits>
#include <list>
#include <map>
#include <sstream>
#include <type_traits>
#include <vector>
#include "yaml-cpp/binary.h"
@@ -94,7 +96,21 @@ struct convert<_Null> {
static Node encode(const type& rhs) { \
std::stringstream stream; \
stream.precision(std::numeric_limits<type>::max_digits10); \
stream << rhs; \
if (std::is_floating_point<type>::value) { \
if (std::isnan(rhs)) { \
stream << ".nan"; \
} else if (std::isinf(rhs)) { \
if (std::signbit(rhs)) { \
stream << "-.inf"; \
} else { \
stream << ".inf"; \
} \
} else { \
stream << rhs; \
} \
} else { \
stream << rhs; \
} \
return Node(stream.str()); \
} \
\

View File

@@ -461,12 +461,66 @@ TEST(NodeTest, FloatingPrecisionFloat) {
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionPositiveInfinityFloat) {
if (!std::numeric_limits<float>::has_infinity) {
return;
}
const float x = std::numeric_limits<float>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNegativeInfinityFloat) {
if (!std::numeric_limits<float>::has_infinity) {
return;
}
const float x = -std::numeric_limits<float>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNanFloat) {
if (!std::numeric_limits<float>::has_quiet_NaN) {
return;
}
const float x = std::numeric_limits<float>::quiet_NaN();
Node node = Node(x);
EXPECT_TRUE(std::isnan(node.as<float>()));
}
TEST(NodeTest, FloatingPrecisionDouble) {
const double x = 0.123456789;
Node node = Node(x);
EXPECT_EQ(x, node.as<double>());
}
TEST(NodeTest, FloatingPrecisionPositiveInfinityDouble) {
if (!std::numeric_limits<double>::has_infinity) {
return;
}
const double x = std::numeric_limits<double>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<float>());
}
TEST(NodeTest, FloatingPrecisionNegativeInfinityDouble) {
if (!std::numeric_limits<double>::has_infinity) {
return;
}
const double x = -std::numeric_limits<double>::infinity();
Node node = Node(x);
EXPECT_EQ(x, node.as<double>());
}
TEST(NodeTest, FloatingPrecisionNanDouble) {
if (!std::numeric_limits<double>::has_quiet_NaN) {
return;
}
const double x = std::numeric_limits<double>::quiet_NaN();
Node node = Node(x);
EXPECT_TRUE(std::isnan(node.as<double>()));
}
TEST(NodeTest, SpaceChar) {
Node node = Node(' ');
EXPECT_EQ(' ', node.as<char>());