【发布时间】:2013-02-11 08:01:09
【问题描述】:
我对这个问题Swap bits in c++ for a double的答案有很大的疑问
然而,这个问题或多或少是我要寻找的: 我从网络收到一个 double,我想在我的机器中正确编码它。
在我收到int 的情况下,我使用ntohl 执行此代码:
int * piData = reinterpret_cast<int*>((void*)pData);
//manage endianness of incomming network data
unsigned long ulValue = ntohl(*piData);
int iValue = static_cast<int>(ulValue);
但如果我收到double,我不知道该怎么办。
问题的答案建议这样做:
template <typename T>
void swap_endian(T& pX)
{
char& raw = reinterpret_cast<char&>(pX);
std::reverse(&raw, &raw + sizeof(T));
}
但是,如果我引用this site:
The ntohl() function converts the unsigned integer netlong from network byte order to host byte order.
When the two byte orders are different, this means the endian-ness of the data will be changed. When the two byte orders are the same, the data will not be changed.
相反,@GManNickG 对问题的回答总是用std::reverse 进行反转。
考虑到这个答案是错误的,我错了吗? (在使用ntohl 建议的字节序网络管理范围内,尽管在OP 问题的标题中没有准确说明)。
最后:我应该将我的double 分成两部分,每部分 4 个字节,然后在这两部分上应用ntohl 函数吗?有没有更规范的解决方案?
C 中还有一个有趣的问题,host to network double?,但它限制为 32 位值。答案说由于架构差异,双打应该转换为字符串......我也将使用音频样本,我真的应该考虑将所有样本转换为我的数据库中的字符串吗? (双打来自我通过网络查询的数据库)
【问题讨论】:
-
数据在本地数据库中的存储方式与网络协议的数据序列化方式不同的情况并不少见。是否要求数据序列化是等价的?
-
你不能结合你链接到的两个解决方案吗?
uint32_t foo = 1; if( htonl(foo) != foo ) { /* GMan's solution goes here */ } else { /* return unmodified argument */ }。此外,关于浮点数表示是不可移植的,第二个答案是正确的,即使字节顺序不是问题。那么您应该转换为字符串,还是为此使用一些专门的库?答案取决于您希望此代码的可移植性。 -
@Praetorian ,所以我必须考虑一下......
-
"双打来自我通过网络查询的数据库" + libpq 标签暗示标准的 postgresql 访问库,它应该已经在为你处理转换......你有麻烦吗?您是否只是假设您需要进行转换,而不是查看检索到的值是否已经可用?
-
@StephaneRolland:哎呀。谷歌搜索显示这是一个常见问题 - 多么好的图书馆!您可以在doxygen.postgresql.org/pqformat_8c.html 看到编码源代码 - 参见
pq_sendfloat8()(也有一个pq_getmsgfloat8(),但不明显如何使用它)。祝你好运。
标签: c++ c network-programming endianness libpq