Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
dota17 committed May 8, 2020
1 parent 0ae471c commit a638406
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
12 changes: 9 additions & 3 deletions include/nlohmann/detail/output/binary_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ class binary_writer

case value_t::number_float:
{
double valueD = j.m_value.number_float;
const auto valueD = j.m_value.number_float;
const float valueF = static_cast<float>(valueD);
if (std::isnan(valueD)) {
// NaN is 0xf97e00 in CBOR
oa->write_character(to_char_type(0xF9));
Expand All @@ -189,8 +190,13 @@ class binary_writer
oa->write_character(valueD > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
oa->write_character(to_char_type(0x00));
} else {
oa->write_character(get_cbor_float_prefix(valueD));
write_number(valueD);
if(static_cast<double>(valueF) == valueD) {
oa->write_character(get_cbor_float_prefix(valueF));
write_number(valueF);
} else {
oa->write_character(get_cbor_float_prefix(valueD));
write_number(valueD);
}
}
break;
}
Expand Down
12 changes: 9 additions & 3 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12164,7 +12164,8 @@ class binary_writer

case value_t::number_float:
{
double valueD = j.m_value.number_float;
const auto valueD = j.m_value.number_float;
const float valueF = static_cast<float>(valueD);
if (std::isnan(valueD)) {
// NaN is 0xf97e00 in CBOR
oa->write_character(to_char_type(0xF9));
Expand All @@ -12176,8 +12177,13 @@ class binary_writer
oa->write_character(valueD > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
oa->write_character(to_char_type(0x00));
} else {
oa->write_character(get_cbor_float_prefix(valueD));
write_number(valueD);
if(static_cast<double>(valueF) == valueD) {
oa->write_character(get_cbor_float_prefix(valueF));
write_number(valueF);
} else {
oa->write_character(get_cbor_float_prefix(valueD));
write_number(valueD);
}
}
break;
}
Expand Down
14 changes: 14 additions & 0 deletions test/src/unit-cbor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,20 @@ TEST_CASE("CBOR")

CHECK(json::from_cbor(result, true, false) == j);
}
SECTION("0.5")
{
double v = 0.5;
json j = v;
// its double-precision float binary value is
// {0xfb, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
// but to save memory, we can store it as single-precision float.
std::vector<uint8_t> expected = {0xfa, 0x3f, 0x00, 0x00, 0x00};
const auto result = json::to_cbor(j);
CHECK(result == expected);
// roundtrip
CHECK(json::from_cbor(result) == j);
CHECK(json::from_cbor(result) == v);
}
}

SECTION("half-precision float (edge cases)")
Expand Down

0 comments on commit a638406

Please sign in to comment.