我尝试在sqlite数据库中更新标志。
我需要从我的旗帜中删除位。目前的旗帜是11。
在Java中我很简单:
newflag = flag ^ 2;
//newflag = 9
在SQL中我尝试:
... SET flag = flag | ~2 ...
现在标记为db = -1。为什么呢?
我在SQLite maganer for Firefox中尝试这个。
SELECT 9 | 2
返回11,但
SELECT 11 | ~2
返回-1
答案 0 :(得分:4)
要回答你的问题(为什么11 | ~2评估为-1),让我们分解它。首先是按位补码:
> SELECT ~2;
-3
使用二进制表示法,这就是发生的事情:
2 : 00000000000000000000000000000010
~2 : 11111111111111111111111111111101
-3 : 11111111111111111111111111111101
SQLite取你的2,应用按位补码,并将其解释为有符号整数。在SQLite中,~n(其中n是整数值)在数学上等效于 - (n)-1,因为它将符号位与所有其他位一起翻转。要更好地理解这一点,请阅读Two's补充:
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中模拟按位XOR,可以使用以下一般形式:
(~(a&b))&(a|b)
http://www.mail-archive.com/sqlite-users@sqlite.org/msg02250.html
答案 1 :(得分:0)
只需标记bsa的非常详尽的答案,以整数形式关闭一点,并使用OP的示例,您可以简单地做到:
SELECT 11 & ~2; -- result is 9
因此,“〜2”除“ 2”位外的其他所有位都打开,并与标志进行按位与运算,强制将2位关闭。
顺便说一句,如果您确定某个特定位为ON,则可以简单地通过减法将其关闭。
例如选择11-2; -结果是9
相反,如果某些位为OFF,则可以通过加法将其打开。