2012-01-04 5 views
1

私は、ハッシュを使用するファイルを扱うプログラムに取り組んでいます。データはブロック長0x1000に分割されます。特定の開始オフセットと終了オフセットを含むセグメントのブロック量を計算する必要があります。このビットワイズ式のロジックを改善しましたか?

たとえば、セグメントの開始オフセットが0x2000、終了が0x3523の場合、0x2000と0x3000の2つのブロックを占めることになります。それは、データブロックの0x2000バイトを占めるわけではありませんが、内部にあるときには「ブロックを占有する」と考えられます。私が最初に考えたのはやっていた。

((EndingOffset - StartingOffset) + 0xFFF) >> 0xC 

これは​​と同等ですが、私はビット演算子とそれらを扱うの課題​​等に新たなんです。

とにかく、ロジックに欠陥があり、開始オフセットが0x3D8Aで、終了オフセットが0x671Dの場合、2つの違いは0x2993です。丸められた値は0x3000、つまり3ブロックです。セグメントは実際には0x3000、0x4000、0x5000、および0x6000の4つを取ります。だから私の次の列車は残念なことに私の最後の列車は、セグメントが入っている最初のブロックのオフセットと、セグメントが入っていない最初のブロックのオフセットとの違いを見つけることでした。

0x3D8Aと私は私が上-複雑Aまし知っ

BlockSize = ((((OffsetEnd + 0xFFF) >> 12) + 1) - ((OffsetStart + 0xFFF) >> 12)); 

:0x671D、これは私がそれを書いた。4.方法がある、私は改善したいものである、成功したブロックの正確な量を得ている、(0x7000 - 0x3000) >> 0xCに私をもたらします単純な問題ですが、私はそれをより良く書く方法の周りに私の小さな脳をラップすることはできません。

編集:それは恥ずかしいです。私はまだかかわらず、完全には思えないその代わりに

(((OffsetEnd + 0xFFF) >> 12) - (OffsetStart >> 12)); 

に来たのか分かりません。

編集2:申し訳ありませんが、終了オフセットは、包括的、排他的ではないことを言及するのを忘れてしまったとセグメント意味の最後のバイトの後の位置です:

(((OffsetEnd - 1 + 0xFFF) >> 12) - (OffsetStart >> 12)); 

編集3:Kerekの答えのオフに行きます、 0から数えると

BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12); 

..or、

BlockSize = (offsetEnd - 1 >> 12) - (offsetStart >> 12); 

EDI:私はで終わりますT 4:私はこだわっています、ゼロからカウントを忘れ:あなたのデータ範囲が[start, end)として与えられていると仮定すると

BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12); 
+0

終了オフセットは包含的か排他的ですか? –

+0

独占。申し訳ありませんが、明らかにする必要があります – mowwwalker

答えて

0

、それは非常に簡単です:

unsigned int start_block = start_offset/0x1000; 
unsigned int end_block = end_offset/0x1000; 

unsigned int number_of_blocks = end_block - start_block + (end_offset > start_offset && end_offset % 0x1000 > 0 ? 1 : 0); 

/ 0x1000のbitfiddling当量が>> 12です、 私は考えます。

データはブロック範囲[start_block、end_block]を占有します。ブロック0は[0x0000,0x1000]であり、ブロック1は[0x1000,0x2000]であることに注意してください。

@Ronが指摘しているように、最後の( "one-past")ブロックが空であるかどうかを区別するためには条件付きが必要で、後者の場合はブロックカウントを1増加させる必要があります。

+0

それは私の最初のロジックでしたが、0x3D8Aは3になり、0x671Dは6になり、数字は4になると3になります。 – mowwwalker

+2

@Walkerneo:いいえ、3番号はゼロから始まります! –

+0

あなたは正しいですか?なぜこれが私に起こらなかったのか分かりません。 – mowwwalker

0

((EndingOffset - StartingOffset)+ 0xFFF)>>から0xC +(!StartingOffset &〜(0xFFF)= 0)

これは、あなたが持っている簡潔な始まりを持っているでしょうし、StartingOffsetがブロックに当たるかどうかはわかります境界かどうか。含まれていない場合は、1を追加してください。

+1

それはもっと複雑に思えます... – mowwwalker

関連する問題