如何从网络上管理double的endianes
How to manage endianess of double from network
我对这个问题的答案有一个大问题用c++中的比特交换双
然而,这个问题或多或少是我所寻找的:我从网络收到一个替身,我想在我的机器中正确编码。
在我收到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));
}
然而,如果我引用这个网站:
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
表明的endianes的网络管理范围内,尽管在OP问题的标题中没有确切地说明(。
最后:我应该把double
分成4个字节的两部分,并在这两部分上应用ntohl
函数吗?还有更多的罐头解决方案吗?
C中还有一个有趣的问题,主机到网络的双重性?,但是它限制为32比特的值。答案是,由于体系结构的差异,双打应该转换为字符串。。。我还将处理音频样本,我真的应该考虑将数据库中的所有样本转换为字符串吗?(双打来自我在网络上查询的数据库(
如果您的double是IEEE 754格式的,那么您应该相对可以。现在您必须将它们的64位分成两个32位的两半,然后以大端顺序(即网络顺序(传输它们;
怎么样:
void send_double(double d) {
long int i64 = *((reinterpret_cast<int *>)(&d)); /* Ugly, but works */
int hiword = htonl(static_cast<int>(i64 >> 32));
send(hiword);
int loword = htonl(static_cast<int>(i64));
send(loword);
}
double recv_double() {
int hiword = ntohl(recv_int());
int loword = ntohl(recv_int());
long int i64 = (((static_cast<long int>) hiword) << 32) | loword;
return *((reinterpret_cast<double *>(&i64));
}
假设您有一个编译时选项来确定endianness:
#if BIG_ENDIAN
template <typename T>
void swap_endian(T& pX)
{
// Don't need to do anything here...
}
#else
template <typename T>
void swap_endian(T& pX)
{
char& raw = reinterpret_cast<char&>(pX);
std::reverse(&raw, &raw + sizeof(T));
}
#endif
当然,另一种选择是根本不通过网络发送double
——考虑到它不能保证与IEEE-754兼容——还有一些机器使用其他浮点格式。。。例如,使用字符串会更好。。。
我无法让John Källén代码在我的机器上工作。此外,将double转换为字节(8位,1个字符(可能更有用:
template<typename T>
string to_byte_string(const T& v)
{
char* begin_ = reinterpret_cast<char*>(v);
return string(begin_, begin_ + sizeof(T));
}
template<typename T>
T from_byte_string(std::string& s)
{
assert(s.size() == sizeof(T) && "Wrong Type Cast");
return *(reinterpret_cast<T*>(&s[0]));
}
此代码也适用于使用POD类型的结构。
如果你真的想双作为两个int
double d;
int* data = reinterpret_cast<int*>(&d);
int first = data[0];
int second = data[1];
最后,long int
并不总是64位整数(我不得不使用long long int
在我的机器上生成64位int(。
如果您想了解系统无端
仅#if __cplusplus > 201703L
#include <bit>
#include <iostream>
using namespace std;
int main()
{
if constexpr (endian::native == endian::big)
cout << "big-endian";
else if constexpr (endian::native == endian::little)
cout << "little-endian";
else
cout << "mixed-endian";
}
有关更多信息:https://en.cppreference.com/w/cpp/types/endian
- C++在数学计算中将double转换为int
- 在c++中为double类型的数组创建一个unique_ptr
- vector<vector<double>> to mxArray using memcpy
- (double) 和 double() 之间的区别
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- C++ Version Of Double.longBitsToDouble
- 错误:类型"double()"和"double()"的操作数无效到二进制&quo
- 有没有办法在C++的赋值中将"char**"转换为"double"?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 使用 std::vector<double> 访问由 std::unique_ptr<double[2] 管理的数据>
- 将 std::vector<double> 从 C++ 包装到 C 以在 Swift 中使用
- 错误:无法将"<lambda(double)>"转换为"double(*)(double)"
- 如何正确将"strings"转换为"double"?
- 如何在<double>矢量中创建复杂类型的模板<T>?
- "double* grade"、"double *grade"和"double* fn()"有什么区别?
- 在不损失精度的情况下将double从C++传输到python
- 重复使用预分配的向量<复杂<double>>作为<double>长度两倍的向量
- 编译器给出错误:format 指定类型 'float *',但参数的类型'double' [-Wformat]
- Zedboard zynq-7000 Opencl 浮点数从类型 'double*' 强制转换为类型 'double' 无效
- 如何从网络上管理double的endianes