altiplano
asked on
Bitwise AND on Double variables
Hi experts,
Apparently the bitwise AND in VBA is limited to long variables. Just try it in the immediate window:
? 2147483648 AND 1
and you get an overflow error (2^31 = 2147483648).
I need to check individual bits in an 8-byte variable, so I'm stuck. Any suggestions?
regards,
Michiel
Apparently the bitwise AND in VBA is limited to long variables. Just try it in the immediate window:
? 2147483648 AND 1
and you get an overflow error (2^31 = 2147483648).
I need to check individual bits in an 8-byte variable, so I'm stuck. Any suggestions?
regards,
Michiel
What is the type of the variable, is it declared as a VB Double?
Do you want to check the individual bits as they are stored in memory (however that is) or is it the logical values - i.e. powers of two?
Do you want to check the individual bits as they are stored in memory (however that is) or is it the logical values - i.e. powers of two?
ASKER
Well, yes, that's what I'm saying. Bitwise AND is apparently limited to long variables, but I need to use it on doubles. So I'm looking for a way to either split a double into two long variables or an alternative AND function.
ASKER
Hi MikeToole,
Yes, I need to check individual bits. Currently I'm using doubles, but I can change that if needed. However, I need at least 50 bits, so long variables are not enough.
Background:
I have a list of patients who are housed in different sections of the building (numbered 1 to 50). A caretaker is only allowed to consult the files of a patient in his/her section. However, some caretakers are assigned to several sections, so they should have access to all patients of those sections.
Caretaker 1: section 1, 4, 5
Caretaker 2: section 3, 4, 7
etc.
The way I want to solve it is by filtering the list of patients using the section number as a bit in a mask. So in the above example the permissionsmask of caretaker 1 would be (binary) 10011. A bitwise AND on the section nr of the patient returns a true or false, which can be used in the queries.
hope this makes sence to you :-)
regards,
Michiel
Yes, I need to check individual bits. Currently I'm using doubles, but I can change that if needed. However, I need at least 50 bits, so long variables are not enough.
Background:
I have a list of patients who are housed in different sections of the building (numbered 1 to 50). A caretaker is only allowed to consult the files of a patient in his/her section. However, some caretakers are assigned to several sections, so they should have access to all patients of those sections.
Caretaker 1: section 1, 4, 5
Caretaker 2: section 3, 4, 7
etc.
The way I want to solve it is by filtering the list of patients using the section number as a bit in a mask. So in the above example the permissionsmask of caretaker 1 would be (binary) 10011. A bitwise AND on the section nr of the patient returns a true or false, which can be used in the queries.
hope this makes sence to you :-)
regards,
Michiel
ASKER
>> permissionsmask of caretaker 1 would be (binary) 10011
This should be right-to-left: 11001
This should be right-to-left: 11001
The limitation looks to be in the AND operator, it doesn't seem to want to return anything than can't go in a Long.
How are the patient records stored, what are you using to filter them?
How are the patient records stored, what are you using to filter them?
ASKER
Thanks for replying.
Heavily simplified it looks like this:
Heavily simplified it looks like this:
tbl_Patients:
ID | Name | Section | pMask
---------------------------------
1 | Andersson | 1 | 1 (bit 1 set)
2 | Johnson | 4 | 8 (bit 4 set)
3 | Parker | 7 | 64 (bit 7 set)
tbl_Caretakers:
ID | Name | cMask
-----------------------
1 | Joe | 65 (bits 1 & 7 set)
2 | Ann | 72 (bits 4 & 7 set)
To list the patients Joe can see, I would query:
SELECT * FROM tbl_Patients WHERE (pMASK AND 65) = pMASK
I see what you mean.
2.147483648e9# and 1 fails
2.147483647e9# and 1 returns 1 which it should
Clearly VBA is converting the double to a long to do the bitwise comparison. It cannot convert 2.147483648e9# so you get an overflow. I can understand this because I cannot get my head around bitwise operations on a float data type. How do you perform bitwise comparisons on the exponent component? I would expect bitwise comparisons would be disallowed on float variables although I have not been able to google an article on the subject.
I think you would need to use two longs to keep track of 50 bits.
2.147483648e9# and 1 fails
2.147483647e9# and 1 returns 1 which it should
Clearly VBA is converting the double to a long to do the bitwise comparison. It cannot convert 2.147483648e9# so you get an overflow. I can understand this because I cannot get my head around bitwise operations on a float data type. How do you perform bitwise comparisons on the exponent component? I would expect bitwise comparisons would be disallowed on float variables although I have not been able to google an article on the subject.
I think you would need to use two longs to keep track of 50 bits.
Found on article. Refers to Basic:
http://support.microsoft.com/kb/61434
http://support.microsoft.com/kb/61434
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thenelson,
Your link doesn't really solve the problem as it merely moves de values from a single to a long, not a double to two longs.
MikeToole,
Your solution is certainly an option. It might put a performance penalty on the query, so I'll have to run a few tests to see if it's workable. However, it also removes the limit of 64 sections, which definately is a plus.
Your link doesn't really solve the problem as it merely moves de values from a single to a long, not a double to two longs.
MikeToole,
Your solution is certainly an option. It might put a performance penalty on the query, so I'll have to run a few tests to see if it's workable. However, it also removes the limit of 64 sections, which definately is a plus.
-2147483648 to 2147483647
Your number is outside the range and hence the overflow!