diff --git a/include/msgpack/v1/pack.hpp b/include/msgpack/v1/pack.hpp index 131c889b..07a89fb1 100644 --- a/include/msgpack/v1/pack.hpp +++ b/include/msgpack/v1/pack.hpp @@ -1138,11 +1138,18 @@ inline packer& packer::pack_unsigned_long_long(unsigned long lon template inline packer& packer::pack_float(float d) { - if (d == int64_t(d)) - { - pack_imp_int64(int64_t(d)); - return *this; + if (d == d) { // check for nan + // compare d to limits::max() to avoid undefined behaviour + if (d >= 0 && d <= std::numeric_limits::max() && d == uint64_t(d)) { + pack_imp_uint64(uint64_t(d)); + return *this; + + } else if (d >= std::numeric_limits::min() && d == int64_t(d)) { + pack_imp_int64(int64_t(d)); + return *this; + } } + union { float f; uint32_t i; } mem; mem.f = d; char buf[5]; @@ -1154,10 +1161,16 @@ inline packer& packer::pack_float(float d) template inline packer& packer::pack_double(double d) { - if (d == int64_t(d)) - { - pack_imp_int64(int64_t(d)); - return *this; + if (d == d) { // check for nan + // compare d to limits::max() to avoid undefined behaviour + if (d >= 0 && d <= std::numeric_limits::max() && d == uint64_t(d)) { + pack_imp_uint64(uint64_t(d)); + return *this; + + } else if (d >= std::numeric_limits::min() && d == int64_t(d)) { + pack_imp_int64(int64_t(d)); + return *this; + } } union { double f; uint64_t i; } mem;