Skip to content

Commit 68acf21

Browse files
committed
pack double and float in a more size efficient way
check also for nan and numeric limits
1 parent 6f0683b commit 68acf21

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

include/msgpack/v1/pack.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,11 +1138,18 @@ inline packer<Stream>& packer<Stream>::pack_unsigned_long_long(unsigned long lon
11381138
template <typename Stream>
11391139
inline packer<Stream>& packer<Stream>::pack_float(float d)
11401140
{
1141-
if (d == int64_t(d))
1142-
{
1143-
pack_imp_int64(int64_t(d));
1144-
return *this;
1141+
if (d == d) { // check for nan
1142+
// compare d to limits::max() to avoid undefined behaviour
1143+
if (d >= 0 && d <= std::numeric_limits<uint64_t>::max() && d == uint64_t(d)) {
1144+
pack_imp_uint64(uint64_t(d));
1145+
return *this;
1146+
1147+
} else if (d >= std::numeric_limits<int64_t>::min() && d == int64_t(d)) {
1148+
pack_imp_int64(int64_t(d));
1149+
return *this;
1150+
}
11451151
}
1152+
11461153
union { float f; uint32_t i; } mem;
11471154
mem.f = d;
11481155
char buf[5];
@@ -1154,10 +1161,16 @@ inline packer<Stream>& packer<Stream>::pack_float(float d)
11541161
template <typename Stream>
11551162
inline packer<Stream>& packer<Stream>::pack_double(double d)
11561163
{
1157-
if (d == int64_t(d))
1158-
{
1159-
pack_imp_int64(int64_t(d));
1160-
return *this;
1164+
if (d == d) { // check for nan
1165+
// compare d to limits::max() to avoid undefined behaviour
1166+
if (d >= 0 && d <= std::numeric_limits<uint64_t>::max() && d == uint64_t(d)) {
1167+
pack_imp_uint64(uint64_t(d));
1168+
return *this;
1169+
1170+
} else if (d >= std::numeric_limits<int64_t>::min() && d == int64_t(d)) {
1171+
pack_imp_int64(int64_t(d));
1172+
return *this;
1173+
}
11611174
}
11621175

11631176
union { double f; uint64_t i; } mem;

0 commit comments

Comments
 (0)