我需要在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;
我假设(但我不确定)存储有符号值的最佳方法是:在存储之前将Val设置为负值的二进制补码位。我已经提出了以下公式,但无法帮助我,但我觉得自己很难为自己做事。
// 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)从未使用过。
问题:
我可以更换吗?
(:Val + (:Val<0) * (1 << BitCount))
同
(:Val & FldBits)
比...更简单
(BigInt & FldBits) - 2 * (BigInt & (1 << (BitCount-1)))
用于检索?
答案 0 :(得分:0)
解决方案(我希望)
采用64位有符号整数BigInt的一般情况,并考虑从位LoBit(基于0)开始并占用BitCount位的有符号位字段。
FldBits = ((1 << BitCount) - 1) << LoBit;
您可以将任意数字Val存储在 - (1&lt;&lt;(BitCount - 1))和(1&lt;(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&amp; 31'进行比较)。
双向移位导致位字段的最高位在所有较高位中被复制。如果Val是+ ve数字,则意味着它用零填充。如果Val是-ve它用填充的那些导致64位整数包含Val的64位表示。