3

倍精度をネットワークバイト順序に変換する方法を教えてもらえますか。私は試した

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コードは素晴らしいでしょう!)。注:OSはLinuxカーネル(2.6.29)、ARMv7CPUアーキテクチャです。

4

2 に答える 2

4

フローティングポイントのフォーマットの交換で IEEE754を見ることができます。

ただし、重要なのは、ネットワークの順序を定義することです。1.バイトの指数と符号、msb順の仮数としてのバイト2からn。

次に、関数を宣言できます

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

実装は、コンパイラ/プラットフォームにのみ依存します。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);
}
于 2012-05-16T20:31:30.280 に答える
1

これはハッキー(char *ハック)かもしれませんが、私にとってはうまくいきます:

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;

}

簡潔にするために、レンジガードは含めていません。ただし、このレベルで作業する場合は、範囲ガードを含める必要があります。

于 2014-01-30T20:23:03.070 に答える