0

オクテット文字列を double の短い配列に変換したい。課題は、2 文字以上を double 値に圧縮することです。1 文字は簡単です (文字の値を使用して double に変換するだけです)。したがって、「a」は「97.0」に変換できます。2 文字は単純にすることもできます。「ab」は「97.98」に変換できます。しかし、どうやって 3 文字を double に変換するのでしょうか? matlab での丸めを考慮してください。

これを行う理由は、すべてのデータを double のみを受け入れる別の製品に送信する必要があるためです。

4

1 に答える 1

0

倍精度は 8 バイト = 64 ビットを使用します。
ASCII 文字は 1 バイトを使用しますが、通常の ASCII エンコーディングは最初の 7 ビットのみを使用します。

したがって、標準の ASCII 文字 (1 ~ 127 の範囲) に制限すると、7*9=63<64 であるため、各 double に 9 文字を収めることができるはずです。

(さらに 1 ビットの余裕があり、7 つの double の各グループに別の文字を入れることもできますが、その最適化は省略します。Unicode の説明も省略しますが、これは多くのアプリケーションで機能します。 )

注意すべきいくつかの Matlab コマンドがあります。

  1. typecast: 基になるビットを変更せずに型変換を実行します。doubleこれを使用して to/fromに変換しuint64ます。

  2. bitshift: 整数データ型でビット シフトを実行します。最下位の N ビットのみを保持して、データを飽和させることもできます。

  3. bitor: 名前が意味することを実行します.. 符号なし整数のビット レベル OR 演算。

次に、少し実験した後、文字列を取得できます。

strIn = 'How much wood could a woodchuck chuck if a woodchuck could chuck wood?';

次に、次のループを使用して、asDouble( 経由で) 配列としてエンコードできます。asUint64

%Convert into doubles.  9 characters per double, 7 bits each.
asUint64 = zeros(1,ceil(length(strIn)/9),'uint64');
for ixChar = 1:length(strIn);
    ixUint64 = ceil(ixChar/9);  %Which uint64 are we writing to?
    ix7Group = mod(ixChar, 9);  %Which 7-bit piece are we writing to?

    %Create the encoded value
    curChar = strIn(ixChar);
    encoded = bitshift(uint64(curChar), ix7Group*7);

    %OR it into the current uint64
    asUint64(ixUint64) = bitor(asUint64(ixUint64), encoded);
end
asDouble = typecast(asUint64,'double');

そして、非常によく似たループを使用して元に戻すことができます

    %Convert back to str
strOut = char(zeros(1,length(asDouble)*9));

asUint64Out =  typecast(asDouble,'uint64');
for ixChar = 1:length(strOut);
    ixUint64 = ceil(ixChar/9);    %Which uint64 are we reading from?
    ix7Group = mod(ixChar, 9);    %Which 7-bit piece are we reading from?

    %Use bitshift to get only the desired bits
    encodedOut = bitshift(asUint64Out(ixUint64), -ix7Group*7, 7);

    %Cast to a char and store
    strOut(ixChar) = char(encodedOut);
end
%Strip unset characters
strOut(strOut==0)=[];

価値のあるものとして、asDouble配列は以下にありますが、この時点で10進数で考えるのはかなり危険です:

>> asDouble'
     5.56929305361178e+196
     6.06383983172222e+259
     8.04093567858749e+177
     3.37314706618397e+259
     2.82456187483837e+266
     1.79945353109827e-150
      3.3731457960492e+259
     2.81037121975641e-306

バイナリはそれについて考えるためのより良い方法であるため:

0110100011000111110101110110101000001110111110111110010000100000
0111010111011111100011010000011001001101111110111111101111101100
0110010011011111101111111011101000001100001010000011001001100011
0111010111010001100011010000011010111100011111010111010001100011
0111011101000001100001010000011001101101001010000011010111101111
0010000011010111100011111010111010001100011110010011011111100011
0111010111010001100011010000011001001101100111010111011111100011
0000000001111111100100110111111011111110111010000011010110000000
于 2013-03-06T00:35:45.277 に答える