【问题标题】:Storing & retrieving signed values from a bit field从位字段存储和检索有符号值
【发布时间】:2017-01-28 15:14:58
【问题描述】:

我需要在 SQLite 中的有符号 64 位整数列 (BigInt) 中存储和检索有符号整数值。为简单起见,假设该字段占用了 BigInt 的第一个 BitCount 位。还假设我们要将记录中的位字段 RowID = :RowID 更改为 :Val 并注意该字段使用的位是 FldBits = (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)从未使用过。

问题:

  1. 我可以替换吗 (:Val + (:Val&lt;0) * (1 &lt;&lt; BitCount))(:Val &amp; FldBits)

  2. 任何比 (BigInt &amp; FldBits) - 2 * (BigInt &amp; (1 &lt;&lt; (BitCount-1))) 检索?

【问题讨论】:

  • 重做表格以将单独的数据放在单独的字段中。这就是数据库的用途。
  • 为什么要在数据库中进行 Bit 操作,我会使用数据库仅用于存储原始数据,如果要对它们进行 Bit 操作,请将它们从数据库中取出,然后然后进行操作。
  • 大笑。通过将单独的数据放在单独的字段中,我没有得到今天的成就。不过说真的,打包的密钥可以加快读取速度。
  • 亚历克斯,为什么会有帮助?

标签: c++ sqlite bit-manipulation


【解决方案1】:

解决方案(我希望)

以 64 位有符号整数 BigInt 的一般情况为例,考虑从 LoBit 位(从 0 开始)开始并占用 BitCount 位的有符号位字段。

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

您可以存储 -(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 数字,则表示它用零填充。如果 Val 是 -ve,它会被填充为 64 位整数,其中包含 Val 的 64 位表示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2013-11-01
    • 2023-04-08
    • 2014-04-02
    • 2021-07-13
    • 2013-11-28
    • 2020-08-09
    相关资源
    最近更新 更多