有效地在 little-endian 和 big-endian 浮点数之间转换
Posted
技术标签:
【中文标题】有效地在 little-endian 和 big-endian 浮点数之间转换【英文标题】:Convert between little-endian and big-endian floats effectively 【发布时间】:2016-12-19 10:36:38 【问题描述】:我有一个工作软件,目前在little-endian
架构上运行。我也想让它在big-endian
模式下运行。我想将little-endian
数据写入文件,无论底层系统的字节序如何。
为了实现这一点,我决定使用 boost endian 库。它可以有效地转换整数。但它不能处理浮点数(和双精度数)。
它在documentation 中声明,“Boost 1.59.0 将支持浮点类型”。但是1.62
仍然不支持它们。
我可以假设,浮点数是有效的 IEEE 754
浮点数(或双精度数)。但是它们的字节顺序可能会根据底层系统而有所不同。据我所知,不建议在浮点数上使用 htonl
和 ntohl
函数。那怎么可能呢?是否有任何仅包含标头的库,它也可以处理浮点数?我找不到任何东西。
我可以将浮点数转换为字符串,然后将其写入文件,我想避免这种方法,原因有很多(性能、磁盘空间、...)
【问题讨论】:
不需要任何库,它非常直接。看看那里:***.com/questions/2782725/… 【参考方案1】:这里:
float f = 1.2f;
auto it = reinterpret_cast<uint8_t*>(&f);
std::reverse(it, it + sizeof(f)); //f is now in the reversed endianness
不需要任何花哨的东西。
【讨论】:
【参考方案2】: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
或者当你使用指针时,立即反转,使用:
template <typename T>
inline T endian_cast(T *t)
#ifdef BOOST_LITTLE_ENDIAN
return boost::endian::endian_reverse_inplace(*t);
#else
return t;
#endif
并使用它,而不是手动(或者可能容易出错)反转它的内容
示例:
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);
祝你好运。
【讨论】:
浮动1 没有过载。但仍然需要强制反转字节序【参考方案3】:在序列化浮点/双精度值时,我做了以下三个假设:
-
机器表示遵循 IEEE 754
float/double 的字节序与整数的字节序匹配
在 double&/int64_t& 或 float&/int32_t& 之间进行 reinterpret_cast-ing 的行为是明确定义的(例如,转换的行为就像类型相似一样)。
标准不保证这些假设。在这些假设下,以下代码将确保双精度以 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));
【讨论】:
我可能应该补充一点,boost::endian::native_to_little_inplace
是在 boost/endian/conversion.hpp 中定义的。以上是关于有效地在 little-endian 和 big-endian 浮点数之间转换的主要内容,如果未能解决你的问题,请参考以下文章
小端格式和大端格式(Little-Endian&Big-Endian)
小端格式和大端格式(Little-Endian&Big-Endian)
小端格式和大端格式(Little-Endian&Big-Endian)