2016-03-25 10 views
1

私は、TBytesからの乱数の読み取りに関連する問題に直面しました。まず、私はこの質問のアドバイスに従いました(ubitstream.pasユニットの使用に関する答え)。Handling arbitrary bit length data in Delphi? 私の例: binaryfeed(TBytes)=(255,0,0,0,0,0,6,132,1,112 、128,128,130,81)。Delphi:TBytesからXビットを読み取る方法は?

  1. 私は8ビットを読み取って255 - okを取得します。位置は8です。
  2. 私は別の24ビットを読んで0 - okを取得します。ポジションは、私がなぜそれを理解することができます0000 0000 0000 0110

    された別の24ビットを読み、位置が56

393216で393216代わりに6の取得32

  • です私はこれらの余分なゼロビットを切り捨てる方法を理解することはできません。何か案は?

  • +0

    この「乱数」は、常に8ビットの倍数ですか?その場合は、バイトを読み取ることができます。これがビッグエンディアンの場合、複数のバイトは次のように整数に結合されます: 'value:= nextByte + value * 256; numBits:= numBits - 8; 'を繰り返します。 –

    +0

    あなたが探しているのが本当に「ビットアクセス」の場合(それはそうではありませんが、@ DavidHeffernanの回答を参照)、System.ClassesのDelphiのTBitsクラスを調べる必要があります。pas –

    答えて

    7

    問題はendiannessです。

    00000110 00000000 00000000 
    

    は3つのバイトを逆393216.であり、あなたは6

    使用しているコードはリトルエンディアンである

    00000000 00000000 00000110 
    

    を持っていますが、ビッグエンディアンの行動を望んでいます。この不一致を考慮してコードを変更する必要があります。

    しかし、私たちが問題に見てきたことから、あなたは常にバイト全体を読んでいるので、使用しているコードの複雑さは必要ありません。バイトレベルで操作できます。明らかにエンディアンを正確に説明する必要がありますが、これはあまり難しいことではありません。

    +0

    >>私たちが問題に見てきたことから、あなたは常にバイト全体を読んでいるので、使用しているコードの複雑さは必要ありません。 私は例えば3ビットの読み込みをサポートする必要があります。 – Maxim

    +0

    問題ありません。なぜなら、常に8の倍数でビットを読み取るからです。問題はエンディアンが問題であるという点です。 –

    0

    まず、あなたのコンテナについて考えてください。バイトを32ビットの整数に読み込む場合は、shr/shlを使用してビットを所定の場所に移動する必要があります。 32ビットの範囲から外に出たくない左端のビットをshrし、残りのX個の位置をshrしてbytevalues(または単語、または必要なサイズ)を取得することは珍しいことではありません。上記のコードで

    var 
        value: integer; 
    begin 
        value := (Readint32FromBuffer shl 8) shr 8; 
        writeln(value.tostring); 
    end; 
    

    、我々はその後、8ビットバック、左に8ビット全部をシフトするので、含まれる最初の8ビットをたくありません。これは、コンテナの「端から外れた」ビットをゼロにします。

    SHLとSHRを使用して変数内でビット/バイトを移動します。しかし、コンテナのサイズを覚えておいてください。

    また、SHLとSHRは通常、CPUレジスタと同じサイズの変数の方が高速ですが、いくつか同じ結果を得るにはANDとORマスクを使用できます( 32ビットまたは64ビット)。

    関連する問題