dbTalk Databases Forums  

[Info-Ingres] bit masks

comp.databases.ingres comp.databases.ingres


Discuss [Info-Ingres] bit masks in the comp.databases.ingres forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Martin Bowes
 
Posts: n/a

Default [Info-Ingres] bit masks - 08-12-2009 , 09:19 AM






Hi All,



How do I tell if a specific bit in the binary representation of an
integer4 item is set?



For example I want to see if the 11th bit is set...in the number 1.



I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;



But these both return 1 when they should return 0.



Running on 9.2.0



Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.



Martin Bowes

Reply With Quote
  #2  
Old   
Roy Hann
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-12-2009 , 11:01 AM






Martin Bowes wrote:


Quote:
How do I tell if a specific bit in the binary representation of an
integer4 item is set?

For example I want to see if the 11th bit is set...in the number 1.

I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;

But these both return 1 when they should return 0.
In general, to test if bit N is on:

select ...
where mod(colx/2**(N-1),2)=1

So for bit 11, it is:

select ...
where mod(colx/2**10,2)=1

or

select ...
where mod(colx/1024,2)=1

Quote:
Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.
Yes, Keith implemented a BIT type.

--
Roy

UK Ingres User Association Conference 2010 will be on Tuesday June 8 2010
Go to http://www.iua.org.uk/join to get on the mailing list.

Reply With Quote
  #3  
Old   
Ian Kirkham
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-12-2009 , 11:09 AM



Hi Marty,

Have a look at the iitables view definition - not pretty but works...
It uses MOD() and integer divide.

Regards,

Ian

________________________________

From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of
Martin Bowes
Sent: 12 August 2009 15:20
To: Ingres and related product discussion forum
Subject: [Info-Ingres] bit masks



Hi All,



How do I tell if a specific bit in the binary representation of an
integer4 item is set?



For example I want to see if the 11th bit is set...in the number 1.



I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;



But these both return 1 when they should return 0.



Running on 9.2.0



Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.



Martin Bowes

Reply With Quote
  #4  
Old   
John Saroka
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-12-2009 , 03:54 PM



Hi Marty:

The bit_and() function seems to work fine as a bit masker:



select hex(bit_and(X'00000401', X'00000001'))\g

00000001



The problem is that it requires operands of type byte, rather than also
allowing the integer types, which are natural for bit-twiddling
(although limited to 8 bytes worth for a single test).



The byte() function has what I think is non-intuitive behavior:



select hex(byte(1,4))\g

31000000 /* integer literal "promoted" to char, I don't think this
is what you wanted */



So then we get

select hex(bit_and(byte(1,4), X'00000400'))\g

00000000 /* the correct byte-by-byte result of AND */



Which is not the same as

select hex(byte(0,4))\g

30000000 /* another number-to-character conversion */



And not the same as

select hex(byte(0))\g

0000 /* I'm assuming the case expr converts the literal 0 to byte,
and the test fails because the lengths are different */



Finally:

select hex(byte(0, 2))\g

3000 /* What I expected for the above query, not sure why it
should be different */



So I believe that the results you're seeing are correct, based on the
peculiarities of byte and byte(). This testing was done on Ingres 9.3.0
int.lnx.

I think the bit_* functions would be much more useful if they took
integer operands, and returned integer values.



Regards,

John



From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of Ian
Kirkham
Sent: Wednesday, August 12, 2009 12:10 PM
To: Ingres and related product discussion forum
Subject: Re: [Info-Ingres] bit masks



Hi Marty,

Have a look at the iitables view definition - not pretty but works...
It uses MOD() and integer divide.

Regards,

Ian

________________________________

From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of
Martin Bowes
Sent: 12 August 2009 15:20
To: Ingres and related product discussion forum
Subject: [Info-Ingres] bit masks



Hi All,



How do I tell if a specific bit in the binary representation of an
integer4 item is set?



For example I want to see if the 11th bit is set...in the number 1.



I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;



But these both return 1 when they should return 0.



Running on 9.2.0



Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.



Martin Bowes

Reply With Quote
  #5  
Old   
Martin Bowes
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-13-2009 , 04:38 AM



Hi John et al,



And to think this all started out as an innocuous and very poorly
phrased question from an evil programmer.



I wasn't confident when I was looking at the bit-wise functions
descriptions in the SQL guide for 9.2.0 and examined the description of
bit_not() and intextract(), neither look good! The description of the
byte() function also sucks a good deal of arse.



It appears that the addition of the optional second parameter to the
byte function causes it to convert the first operand (an integer) to a
char. Which was not what I would expect!

For example:

1) select hex(byte(1,1)); --> yields 31

2) select hex(byte(1)); --> yields 0100

3) select hex('1'); --> yields 31

4) select hex(1); --> yields 0001



This was done on II 9.2.0 (a64.lnx/143)NPTL + 13468.



The output from the second and fourth line leads me to wonder whether or
not the byte function is correctly handling big-endian/little endian
features. I'm reasonably confident the hex() function is OK. Try select
hex(256).

The hex() function clearly displays data in a big-endian format. Which
is cool as it has to handle all the data types so I expect hex('ABC') to
display 414243 as the 'A' should come before the 'C' in memory.



But Linux is little endian, so an integer 1 is stored in memory order as
01 00. So the byte function is storing in big endian format 00 01



But I can now put all of this togethor and allow for the big-endian,
little-endian and generaly screwed nature of this by adjusting my bit
mask and writing....

select case when bit_and(byte(int4(1024)), X'00040000') != byte(int4(0))
then 1 else 0 end as bit_11_set;



I'm thinking:

* The mod and div feature mentioned elsewhere is the preferred
option....

* The byte(m,n) function is broken.

* This was not the best way to spend a morning.



Quote:
I think the bit_* functions would be much more useful if they took
integer operands, and returned integer values.

Absolutley!



Marty





From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of John
Saroka
Sent: 12 August 2009 21:55
To: Ingres and related product discussion forum
Subject: Re: [Info-Ingres] bit masks



Hi Marty:

The bit_and() function seems to work fine as a bit masker:



select hex(bit_and(X'00000401', X'00000001'))\g

00000001



The problem is that it requires operands of type byte, rather than also
allowing the integer types, which are natural for bit-twiddling
(although limited to 8 bytes worth for a single test).



The byte() function has what I think is non-intuitive behavior:



select hex(byte(1,4))\g

31000000 /* integer literal "promoted" to char, I don't think this
is what you wanted */



So then we get

select hex(bit_and(byte(1,4), X'00000400'))\g

00000000 /* the correct byte-by-byte result of AND */



Which is not the same as

select hex(byte(0,4))\g

30000000 /* another number-to-character conversion */



And not the same as

select hex(byte(0))\g

0000 /* I'm assuming the case expr converts the literal 0 to byte,
and the test fails because the lengths are different */



Finally:

select hex(byte(0, 2))\g

3000 /* What I expected for the above query, not sure why it
should be different */



So I believe that the results you're seeing are correct, based on the
peculiarities of byte and byte(). This testing was done on Ingres 9.3.0
int.lnx.

I think the bit_* functions would be much more useful if they took
integer operands, and returned integer values.



Regards,

John



From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of Ian
Kirkham
Sent: Wednesday, August 12, 2009 12:10 PM
To: Ingres and related product discussion forum
Subject: Re: [Info-Ingres] bit masks



Hi Marty,

Have a look at the iitables view definition - not pretty but works...
It uses MOD() and integer divide.

Regards,

Ian

________________________________

From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of
Martin Bowes
Sent: 12 August 2009 15:20
To: Ingres and related product discussion forum
Subject: [Info-Ingres] bit masks



Hi All,



How do I tell if a specific bit in the binary representation of an
integer4 item is set?



For example I want to see if the 11th bit is set...in the number 1.



I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;



But these both return 1 when they should return 0.



Running on 9.2.0



Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.



Martin Bowes

Reply With Quote
  #6  
Old   
Ingres Forums
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-13-2009 , 05:20 AM



Any plans to put BIT type into some of (near) future Ingres 10 versions?


--
dejan

Reply With Quote
  #7  
Old   
John Saroka
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-13-2009 , 08:40 AM



Marty:

I also got trapped in the morass of byte+endians playing with this
yesterday. "Enough!" I said. Just let me do this:

select bit_and(intval1, intval2) as intval3;

Or even

select intval1 && intval2 as intval3;

It's portable, and has no harmful side-effects!

Cheers

John



From: Martin Bowes [mailto:martin.bowes (AT) ctsu (DOT) ox.ac.uk]
Sent: Thursday, August 13, 2009 5:38 AM
To: Ingres and related product discussion forum
Cc: John Saroka
Subject: RE: [Info-Ingres] bit masks



Hi John et al,



And to think this all started out as an innocuous and very poorly
phrased question from an evil programmer.



I wasn't confident when I was looking at the bit-wise functions
descriptions in the SQL guide for 9.2.0 and examined the description of
bit_not() and intextract(), neither look good! The description of the
byte() function also sucks a good deal of arse.



It appears that the addition of the optional second parameter to the
byte function causes it to convert the first operand (an integer) to a
char. Which was not what I would expect!

For example:

1) select hex(byte(1,1)); --> yields 31

2) select hex(byte(1)); --> yields 0100

3) select hex('1'); --> yields 31

4) select hex(1); --> yields 0001



This was done on II 9.2.0 (a64.lnx/143)NPTL + 13468.



The output from the second and fourth line leads me to wonder whether or
not the byte function is correctly handling big-endian/little endian
features. I'm reasonably confident the hex() function is OK. Try select
hex(256).

The hex() function clearly displays data in a big-endian format. Which
is cool as it has to handle all the data types so I expect hex('ABC') to
display 414243 as the 'A' should come before the 'C' in memory.



But Linux is little endian, so an integer 1 is stored in memory order as
01 00. So the byte function is storing in big endian format 00 01



But I can now put all of this togethor and allow for the big-endian,
little-endian and generaly screwed nature of this by adjusting my bit
mask and writing....

select case when bit_and(byte(int4(1024)), X'00040000') != byte(int4(0))
then 1 else 0 end as bit_11_set;



I'm thinking:

* The mod and div feature mentioned elsewhere is the preferred
option....

* The byte(m,n) function is broken.

* This was not the best way to spend a morning.



Quote:
I think the bit_* functions would be much more useful if they took
integer operands, and returned integer values.

Absolutley!



Marty





From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of John
Saroka
Sent: 12 August 2009 21:55
To: Ingres and related product discussion forum
Subject: Re: [Info-Ingres] bit masks



Hi Marty:

The bit_and() function seems to work fine as a bit masker:



select hex(bit_and(X'00000401', X'00000001'))\g

00000001



The problem is that it requires operands of type byte, rather than also
allowing the integer types, which are natural for bit-twiddling
(although limited to 8 bytes worth for a single test).



The byte() function has what I think is non-intuitive behavior:



select hex(byte(1,4))\g

31000000 /* integer literal "promoted" to char, I don't think this
is what you wanted */



So then we get

select hex(bit_and(byte(1,4), X'00000400'))\g

00000000 /* the correct byte-by-byte result of AND */



Which is not the same as

select hex(byte(0,4))\g

30000000 /* another number-to-character conversion */



And not the same as

select hex(byte(0))\g

0000 /* I'm assuming the case expr converts the literal 0 to byte,
and the test fails because the lengths are different */



Finally:

select hex(byte(0, 2))\g

3000 /* What I expected for the above query, not sure why it
should be different */



So I believe that the results you're seeing are correct, based on the
peculiarities of byte and byte(). This testing was done on Ingres 9.3.0
int.lnx.

I think the bit_* functions would be much more useful if they took
integer operands, and returned integer values.



Regards,

John



From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of Ian
Kirkham
Sent: Wednesday, August 12, 2009 12:10 PM
To: Ingres and related product discussion forum
Subject: Re: [Info-Ingres] bit masks



Hi Marty,

Have a look at the iitables view definition - not pretty but works...
It uses MOD() and integer divide.

Regards,

Ian

________________________________

From: info-ingres-bounces (AT) kettleriver...ting (DOT) com
[mailto:info-ingres-bounces (AT) kettleriverconsulting (DOT) com] On Behalf Of
Martin Bowes
Sent: 12 August 2009 15:20
To: Ingres and related product discussion forum
Subject: [Info-Ingres] bit masks



Hi All,



How do I tell if a specific bit in the binary representation of an
integer4 item is set?



For example I want to see if the 11th bit is set...in the number 1.



I've tried...

select case when bit_and(byte(1, 4), X'00000400') != byte(0, 4) then 1
else 0 end as bit_11_set;

select case when bit_and(byte(1, 4), X'00000400') != 0 then 1 else 0 end
as bit_11_set;



But these both return 1 when they should return 0.



Running on 9.2.0



Are there bit masking functions? IIRC these were being deveolped in the
last Ingres Codesprint in London but it may be some time before they are
available.



Martin Bowes

Reply With Quote
  #8  
Old   
Ingres Forums
 
Posts: n/a

Default Re: [Info-Ingres] bit masks - 08-13-2009 , 09:31 PM



Quote:
Any plans to put BIT type into some of (near) future Ingres 10 versions?


Maybe....it's not on the 10.0 list for internal development, but some
work was done at the recent sprint at the UKIUA on it, so there is a
good chance it will get into a release soon (maybe 10.0 if the timing is
right).


--
stephenb

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.