【问题标题】:how to convert double between host and network byte order?如何在主机和网络字节顺序之间转换双精度?
【发布时间】:2012-05-23 22:01:51
【问题描述】:

谁能告诉我如何将双精度转换为网络字节顺序。 我试过了

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

函数,它们运行良好,但它们都没有进行双重(浮点)转换,因为这些类型在每个架构上都是不同的。通过 XDR,我发现了双浮点精度格式表示(http://en.wikipedia.org/wiki/Double_precision),但那里没有字节排序。

所以,如果有人能帮助我解决这个问题,我将不胜感激(C 代码会很棒!)。 注意:操作系统是 Linux 内核 (2.6.29),ARMv7 CPU 架构。

【问题讨论】:

  • double 没有网络字节顺序,因为它们没有单一定义的网络表示。如果你真的想要或将它们表示为分子和分母,你可以将它们分解为尾数、符号和指数,但这很繁琐。

标签: networking linux-kernel embedded arm endianness


【解决方案1】:

您可以查看IEEE 754 的浮点交换格式。

但关键应该是定义网络顺序,例如。 1. 字节指数和符号,字节 2 到 n 作为 msb 顺序的尾数。

然后你可以声明你的函数

uint64_t htond(double hostdouble);
double ntohd(uint64_t netdouble);

实现仅取决于您的编译器/平台。
最好的应该是使用一些 natural 的定义, 所以你可以在 ARM 平台上使用简单的转换。

编辑:

来自评论

static void htond (double &x)
{
  int *Double_Overlay; 
  int Holding_Buffer; 
  Double_Overlay = (int *) &x; 
  Holding_Buffer = Double_Overlay [0]; 
  Double_Overlay [0] = htonl (Double_Overlay [1]); 
  Double_Overlay [1] = htonl (Holding_Buffer); 
}

这可行,但显然只有两个平台对 double 使用相同的编码模式并且 int 具有相同的 long 大小。
顺便提一句。返回值的方式有点奇怪。

但是你可以写一个更稳定的版本,像这样(伪代码)

void htond (const double hostDouble, uint8_t result[8])
{
  result[0] = signOf(hostDouble);
  result[1] = exponentOf(hostDouble);
  result[2..7] = mantissaOf(hostDouble);
}

【讨论】:

  • 我发现了这个,但在服务器上收到了意外的值。 static void htond (double &x) { int *Double_Overlay; int 持有缓冲区; Double_Overlay = (int *) &x; Holding_Buffer = Double_Overlay [0]; Double_Overlay [0] = htonl (Double_Overlay [1]); Double_Overlay [1] = htonl (Holding_Buffer); }
【解决方案2】:

这可能是 hacky(char* hack),但它对我有用:

double Buffer::get8AsDouble(){

    double little_endian = *(double*)this->cursor;

    double big_endian;

    int x = 0;
    char *little_pointer = (char*)&little_endian;
    char *big_pointer = (char*)&big_endian;

    while( x < 8 ){
        big_pointer[x] = little_pointer[7 - x];
        ++x;
    }

    return big_endian;

}

为简洁起见,我没有包括范围守卫。不过,在此级别工作时,您应该包括范围守卫。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-23
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    相关资源
    最近更新 更多