如何以可移植的方式将integer转换为little-endian
How to convert integer to little-endian in a portable way
我想知道以可移植的方式将integer转换为little-endian的推荐方法是什么。
有图书馆吗?
我们可以使用htonl和ntohl,然后进行另一个big-endian到little-endian的转换,但这并不有效。
可移植的方法是将位偏移和掩码用于适当大小的字符串。请注意,我说的是字符串,因为这实际上是您唯一需要关注endianness的时间——在系统之间传输字节时。
如果您想避免不必要的转换(例如,在little-endian体系结构上转换为little-eddian),那么在编译时没有完全可移植的方法。但是,您可以在运行时进行检查以动态选择转换函数集。
这确实有代码无法内联的缺点。以可移植的方式编写转换并使用模板或内联可能更有效。结合半可移植的编译时检查,这将是您所能得到的最好结果。
进一步阅读:在编译时检测Endianness。
这是一个很好的问题。它促使我查看是否有任何方法可以在编译时使用constexpr表达式来确定endianness。
事实证明,如果没有预处理器技巧,这是不可能的,因为在constexpr上下文中进行求值时,无法将整数转换为字节序列(通过强制转换或并集)。
然而事实证明,在gcc中,使用-O2编译时,一个简单的运行时检查会得到优化,因此这实际上是最有效的:
#include <cstdint>
#include <iostream>
constexpr bool is_little_endian()
{
union endian_tester {
std::uint16_t n;
std::uint8_t p[4];
};
constexpr endian_tester sample = {0x0102};
return sample.p[0] == 0x2;
}
template<class Int>
Int to_little_endian(Int in)
{
if (is_little_endian()) {
return in;
}
else {
Int out = 0;
std::uint8_t* p = reinterpret_cast<std::uint8_t*>(std::addressof(out));
for (std::size_t byte = 0 ; byte < sizeof(in) ; ++byte)
{
auto part = (in >> (byte * 8)) & 0xff;
*p++ = std::uint8_t(part);
}
return out;
}
}
int main()
{
auto x = to_little_endian(10);
std::cout << x << std::endl;
}
以下是在intel(little-endian)平台上编译时的汇编程序输出:
main:
subq $8, %rsp
#
# here is the call to to_little_endian()
#
movl $10, %esi
#
# that was it - it's been completely optimised away
#
movl std::cout, %edi
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
xorl %eax, %eax
addq $8, %rsp
ret
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 将cryptopp :: Integer转换为lpctstr
- 从 cryptopp::integer 转换为 QString
- 将Integer转换为Little Endian十六进制字符串
- 将Integer转换回SecByteBlock
- 如何以可移植的方式将integer转换为little-endian
- integer可以被类型转换为指向integer的指针
- 我怎么能相信从double到integer的强制转换
- 如何将Integer句柄转换为HWND
- 如何将 CryptoPP::Integer 转换为 char*
- boost::multiprecision从integer转换为cpp_dec_foat编译错误
- C++、Integer和Char数组转换故障
- 整数到char*和char*到Integer的转换
- 在C++中,键入将结构强制转换为integer,反之亦然
- 将std::string转换为integer时,如何处理上溢/下溢
- 将integer转换为函数参数的字符串
- 键入强制转换为integer