pack double and float in a more size efficient way

check also for nan and numeric limits
This commit is contained in:
GeorgFritze
2022-06-02 10:40:51 +02:00
parent 6f0683bb46
commit 68acf21a8e

View File

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