[英]Convert between little-endian and big-endian floats effectively
I have a working software, which currently runs on a little-endian
architecture.我有一个可以运行的软件,它目前在little-endian
架构上运行。 I would like to make it run in big-endian
mode too.我也想让它以big-endian
模式运行。 I would like to write little-endian
data into files, regardless of the endianness of the underlying system.无论底层系统的字节序如何,我都想将little-endian
数据写入文件。
To achieve this, I decided to use the boost endian library.为了实现这一点,我决定使用 boost endian 库。 It can convert integers efficiently.它可以有效地转换整数。 But it cannot handle floats (and doubles).但它不能处理浮动(和双打)。
It states in the documentation , that " Floating point types will be supported in the Boost 1.59.0 ".它在文档中指出,“ Boost 1.59.0 将支持浮点类型”。 But they are still not supported in 1.62
.但是它们在1.62
中仍然不受支持。
I can assume, that the floats are valid IEEE 754
floats (or doubles).我可以假设,浮点数是有效的IEEE 754
浮点数(或双精度数)。 But their endianness may vary according to the underlying system.但是它们的字节顺序可能会因底层系统而异。 As far as I know, using the htonl
and ntohl
functions on floats is not recommended.据我所知,不建议在浮动上使用htonl
和ntohl
函数。 How is it possible then?那怎么可能呢? Is there any header-only library, which can handle floats too?是否有任何头文件库,它也可以处理浮点数? I was not able to find any.我找不到任何东西。
I could convert the floats to string, and write that into a file, I would like to avoid that method, for many reasons ( performance, disk-space, ... )我可以将浮点数转换为字符串,并将其写入文件,出于多种原因(性能、磁盘空间……),我想避免使用该方法
Here:这里:
float f = 1.2f;
auto it = reinterpret_cast<uint8_t*>(&f);
std::reverse(it, it + sizeof(f)); //f is now in the reversed endianness
No need for anything fancy.不需要任何花哨的东西。
Unheilig: you are correct, but Unheilig:你是对的,但是
#include <boost/endian/conversion.hpp>
template <typename T>
inline T endian_cast(const T & t)
{
#ifdef BOOST_LITTLE_ENDIAN
return boost::endian::endian_reverse(t);
#else
return t;
#endif
}
or when u are using pointers, to immediate reversing, use:或者当您使用指针时,要立即反转,请使用:
template <typename T>
inline T endian_cast(T *t)
{
#ifdef BOOST_LITTLE_ENDIAN
return boost::endian::endian_reverse_inplace(*t);
#else
return t;
#endif
}
and use it, instead of manually (or maybe error-prone) reversing it's content并使用它,而不是手动(或者可能容易出错)反转它的内容
example:例子:
std::uint16_t start_address() const
{
std::uint16_t address;
std::memcpy(&address, &data()[1], 2);
return endian_cast(address);
}
void start_address(std::uint16_t i)
{
endian_cast(&i);
std::memcpy(&data()[1], &i, 2);
}
Good luck.祝你好运。
When serializing float/double values, I make the following three assumptions:在序列化 float/double 值时,我做出以下三个假设:
None of these assumptions is guaranteed by the standard.这些假设都不是由标准保证的。 Under these assumptions, the following code will ensure doubles are written in little-endian:在这些假设下,以下代码将确保以小端顺序编写双打:
ostream out;
double someVal;
...
static_assert(sizeof(someVal) == sizeof(int64_t),
"Endian conversion requires 8-byte doubles");
native_to_little_inplace(reinterpret_cast<int64_t&>(someVal));
out.write(reinterpret_cast<char*>(&someVal), sizeof(someVal));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.