Subject Re: [firebird-support] How to invert a bitmask?
Author Michael Ludwig
Paul Vinkenoog schrieb am 10.05.2010 um 04:49:33 (+0200):
> Michael Ludwig wrote:
>
> > How can I invert a bitmask in Firebird/PSQL (such as
> > with ~ in Perl)?
>
> XOR with a number where all the bits are 1. For signed
> numbers in two's complement format, this is always -1.
> For unsigned numbers, this is 2^n - 1 (with n the number
> of bits).
>
> So, Firebird's INTEGER and BIGINT being signed,
> BIN_XOR(number, -1) should do the trick. Do test it,
> though!

So -1 has all bits set for signed numbers. Now let's say
I want to clear bit 10 on some number (1999). I can make a
bitmask for clearing by doing BIN_XOR(-1, BIN_SHL(1,10)).
So, to clear the bit on my number:

SELECT BIN_AND( 1999, BIN_XOR( -1, BIN_SHL(1, 10) ) )
FROM RDB$DATABASE;

Thanks! It seems to work:

SQL> select a, bin_and( 1023, bin_xor( -1, bin_shl(1, a) )) from t;

A BIN_AND
============ =====================
0 1022
1 1021
2 1019
3 1015
4 1007
5 991
6 959
7 895
8 767
9 511
10 1023

SQL> select a, bin_and( 1024, bin_xor( -1, bin_shl(1, a) )) from t;

A BIN_AND
============ =====================
0 1024
1 1024
2 1024
3 1024
4 1024
5 1024
6 1024
7 1024
8 1024
9 1024
10 0

--
Michael Ludwig