[英]Convert between little-endian and big-endian floats effectively
我有一個可以運行的軟件,它目前在little-endian
架構上運行。 我也想讓它以big-endian
模式運行。 無論底層系統的字節序如何,我都想將little-endian
數據寫入文件。
為了實現這一點,我決定使用 boost endian 庫。 它可以有效地轉換整數。 但它不能處理浮動(和雙打)。
它在文檔中指出,“ Boost 1.59.0 將支持浮點類型”。 但是它們在1.62
中仍然不受支持。
我可以假設,浮點數是有效的IEEE 754
浮點數(或雙精度數)。 但是它們的字節順序可能會因底層系統而異。 據我所知,不建議在浮動上使用htonl
和ntohl
函數。 那怎么可能呢? 是否有任何頭文件庫,它也可以處理浮點數? 我找不到任何東西。
我可以將浮點數轉換為字符串,並將其寫入文件,出於多種原因(性能、磁盤空間……),我想避免使用該方法
這里:
float f = 1.2f;
auto it = reinterpret_cast<uint8_t*>(&f);
std::reverse(it, it + sizeof(f)); //f is now in the reversed endianness
不需要任何花哨的東西。
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);
}
祝你好運。
在序列化 float/double 值時,我做出以下三個假設:
這些假設都不是由標准保證的。 在這些假設下,以下代碼將確保以小端順序編寫雙打:
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.