2017-01-28 3 views
3

SQLiteの符号付き64ビット整数列(BigInt)との間で符号付き整数値を格納および取得する必要があります。簡単にするために、フィールドがBigIntの最初のBitCountビットを占めているとします。また、RowID =:RowIDを持つレコードのビットフィールドをValに変更し、フィールドで使用されるビットがFldBits =(1 < < BitCount)-1であることに注意してください。ビットフィールドからの符号付き値の格納と取得

符号なし価値は、記憶と検索が十分に簡単です。

// Store 
update BigIntTbl set BigInt = BigInt & ~FldBits | :Val 
where RowID=:RowID; 

// Retrieve 
select BigInt & FldBits 
from BigIntTbl where RowID=:RowID; 

私は仮定している(しかし、私は確かに意味がないでよ)付きの値を格納するための最良の方法を設定していること:ヴァルを負の値の2の補数ビットに格納する前に。私は次の公式を思いついたが、助けてくれるとは思えないが、自分自身のために物事を頑張っていると感じている。私はちょうど適用について考えなかった

// Store 
update BigIntTbl set BigInt = BigInt & ~FldBits | 
(:Val + (:Val<0) * (1 << BitCount)) 
// above sets :Val to 2s complement bit pattern for -ve values and leaves +ve values unchanged 

// Retreive 
select (BigInt & FldBits) - 2 * (BigInt & (1 << (BitCount-1))) 
from BigIntTbl where RowID=:RowID; 

オフセット(すなわち格納するときのオフセットを追加取得する際に、オフセット控除)しかし、私はしませんが理由のために、私はゼロとして格納されるようにゼロにしたいです。明確にするために、BigIntの符号ビット(ビット63)は決して使用されないものと仮定する。

質問:

  1. 私は検索のため (BigInt & FldBits) - 2 * (BigInt & (1 << (BitCount-1))) よりも簡単 (:Val & FldBits)

  2. 何かで (:Val + (:Val<0) * (1 << BitCount)) 置き換えることはできますか?

+1

別のフィールドに別々のデータを入れるためにテーブルをやり直してください。それがデータベースの目的です。 – stark

+0

なぜビット操作をデータベース内でやりたいのですか?ビット操作を行い、データベースから取り出して操作したい場合は、生データを格納するためだけにデータベースを使用します。 – Alex

+0

LOL stark。別々のデータを別々のフィールドに入れて、私が今日どこにいるのか分かりませんでした。真剣に、パックされたキーは読み込みを高速化できます。 – NoComprende

答えて

0

溶液(私は願って)

は、64ビット符号付き整数のBigIntの一般的な場合を取ると、(ベース0)ビットLoBitで開始しBITCOUNTビットを占有する符号付きビットフィールドを考えます。

FldBits = ((1 << BitCount) - 1) << LoBit; 

あなたが間の任意の数のValを保存することができます - (1 < <(BITCOUNT - 1))と、(1 < <(BITCOUNT - 1)) - 1

BigInt = BigInt & ~FldBits | (Val << LoBit & FldBits) 

とし、それを取得

Val = (BigInt & FldBits) << (64 - BitCount - LoBit) >> (64 - BitCount); 

簡単なSQLの例

select (?1 & 31) <<59>> 59; 

?1の-16と15の間の値は?1を返します( 'select?1 & 31'と比較してください)。

ビット・フィールドの最上位ビットがすべての上位ビットで複製されます。 Valが+ veであれば、0で埋められます。 Valが-veならば、それは64ビット表現のValを含む64ビット整数になる。

関連する問題