0

我尝试更新 sqlite 数据库中的标志。

我需要从我的标志中删除位。当前标志值为 11。

在Java中我很简单:

newflag = flag  ^ 2;
//newflag = 9

在 SQL 中,我尝试:

... SET flag = flag | ~2 ...

现在在 db = -1 中标记。为什么?

我在 Firefox 的 SQLite magener 中尝试了这个。

SELECT 9 | 2

返回 11,但是

SELECT 11 | ~2

返回 -1

4

2 回答 2

4

要回答您的问题(为什么 11 | ~2 评估为 -1),让我们分解一下。首先是按位补码:

> SELECT ~2;
-3

使用二进制表示法,这就是正在发生的事情:

 2 : 00000000000000000000000000000010
~2 : 11111111111111111111111111111101
-3 : 11111111111111111111111111111101

SQLite 采用您的 2,应用按位补码,并将其解释为有符号整数。在 SQLite 中,~n(其中 n 是一个整数值)在数学上等价于 -(n)-1,因为它将符号位与所有其他位一起翻转。为了更好地理解这一点,请阅读二进制补码:

http://en.wikipedia.org/wiki/Two's_complement

接下来按位或:

> SELECT 11 | ~2;
-1

再次以二进制形式:

     11 : 00000000000000000000000000001011
     ~2 : 11111111111111111111111111111101
11 | ~2 : 11111111111111111111111111111111
     -1 : 11111111111111111111111111111111

至于模拟您的 Java:您的 Java 使用按位 XOR 运算符 (^)。要在 sqlite 中模拟按位异或,您可以使用以下通用形式:

(~(a&b))&(a|b)

http://www.mail-archive.com/sqlite-users@sqlite.org/msg02250.html

于 2013-05-08T14:14:40.513 回答
0

只需标记 bsa 非常彻底的答案,关闭整数位,并使用 OP 的示例,您可以简单地:

SELECT 11 & ~2;  -- result is 9

所以“~2”除了“2”位之外的所有位都打开,并与标志执行按位与,强制关闭 2 位。

顺便说一句,如果您确定某个特定位为 ON,则只需通过减法即可将其关闭。

例如选择 11 - 2;-- 结果是 9

反之,如果某个位为OFF,则可以通过加法将其打开。

于 2020-01-28T17:55:11.587 回答