♻️ implement floating-point special values

This commit is contained in:
Niels Lohmann 2021-09-11 14:27:38 +02:00
parent 6bfd21e321
commit 5221115ff1
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
3 changed files with 46 additions and 6 deletions

View File

@ -1593,6 +1593,14 @@ class binary_writer
{ {
oa->write_character(to_char_type(0xFD)); oa->write_character(to_char_type(0xFD));
} }
else if (std::isnan(j.m_value.number_float))
{
oa->write_character(to_char_type(0x8E));
oa->write_character(to_char_type(0x7F));
oa->write_character(to_char_type(0x80));
oa->write_character(to_char_type(0x00));
oa->write_character(to_char_type(0x01));
}
else else
{ {
// write float with prefix // write float with prefix
@ -1839,9 +1847,9 @@ class binary_writer
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wfloat-equal"
#endif #endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) && if (std::isnan(n) || std::isinf(n) || (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) && static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n)) static_cast<double>(static_cast<float>(n)) == static_cast<double>(n)))
{ {
switch (format) switch (format)
{ {

View File

@ -15167,6 +15167,14 @@ class binary_writer
{ {
oa->write_character(to_char_type(0xFD)); oa->write_character(to_char_type(0xFD));
} }
else if (std::isnan(j.m_value.number_float))
{
oa->write_character(to_char_type(0x8E));
oa->write_character(to_char_type(0x7F));
oa->write_character(to_char_type(0x80));
oa->write_character(to_char_type(0x00));
oa->write_character(to_char_type(0x01));
}
else else
{ {
// write float with prefix // write float with prefix
@ -15413,9 +15421,9 @@ class binary_writer
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wfloat-equal"
#endif #endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) && if (std::isnan(n) || std::isinf(n) || (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) && static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n)) static_cast<double>(static_cast<float>(n)) == static_cast<double>(n)))
{ {
switch (format) switch (format)
{ {

View File

@ -468,6 +468,30 @@ TEST_CASE("BON8")
const auto result = json::to_bon8(j); const auto result = json::to_bon8(j);
CHECK(result == expected); CHECK(result == expected);
} }
SECTION("NAN")
{
json j = NAN;
std::vector<uint8_t> expected = {0x8E, 0x7F, 0x80, 0x00, 0x01};
const auto result = json::to_bon8(j);
CHECK(result == expected);
}
SECTION("infinity")
{
json j = INFINITY;
std::vector<uint8_t> expected = {0x8E, 0x7F, 0x80, 0x00, 0x00};
const auto result = json::to_bon8(j);
CHECK(result == expected);
}
SECTION("-infinity")
{
json j = -INFINITY;
std::vector<uint8_t> expected = {0x8E, 0xFF, 0x80, 0x00, 0x00};
const auto result = json::to_bon8(j);
CHECK(result == expected);
}
} }
SECTION("floats") SECTION("floats")