Bit comparisons

B

Bill

I'm trying to sort out what I can find in HELP
regarding the use of bit string functions, but so
far I've not found how to accomplish that.
It may very well be that I don't have the right
slant on setting the data type correctly?

Example:
If I have two 16-bit bit strings:

bitI = 0000000010000000
bitJ = 0001001010000001

and I want to know if the "1" bit in string
bitI is also present in bit-string bitJ.

What Dim is appropriate and what function
applies such that:

bitI somefunction bitJ = 1

?

Ultimately, I need to use this function in the
WHERE clause of a SQL query. (Actually,
it would likely be used in a filter expression
set at runtime.)
 
D

Douglas J. Steele

You can declare them as Long Integers, and use And (or Or) to manipulate
them. Recognize, though, that Anding them will not result in 1: it will
result in 0000000010000000 (128).

Unfortunately, there's nothing built into Access to convert binary to
numbers, so you'll need your own function.

The following untested air-code should work:

Function BinaryToInteger(BinaryString As String) As Long
Dim intloop As Integer
Dim intLen As Integer
Dim lngValue As Long

intLen = Len(BinaryString)
If intLen <= 16 Then
For intloop = 1 To intLen
If Mid(BinaryString, intloop, 1) = "1" Then
lngValue = lngValue + 2 ^ (intLen - intloop)
End If
Next intloop
End If

BinaryToInteger = lngValue

End Function

You'd use that as

BinaryToInteger("0000000010000000") And BinaryToInteger("0001001010000001")
 
B

Bill

Hi Doug,
Yes, I'd already run into the conversion issue as I attempted
to formulate some sample code approaches.

Perhaps I'd have simpler looking code segments were I to
use an array approach? I.e., have 16 elements of type bit.
Thus, my originally posted example would look more like:

If bitI(8) = bitJ(8) then BLAH BLAH BLAH

This may all be for naught, as I'm restricted in table field-defs
to number-integer to create fields of length 16 bits and then
wouldn't that put me right back in the conversion problem
again?

Another approach would be to have 16 1-byte table fields
and reference them in code using Field-Collection notation.
Like, fld0; fld1; fld2;..........fld15 and reference as
FieldsCollection("fld" & MyIndex). This approach expands
a portion of four of my tables by a factor of eight, but perhaps
that's a small price to pay considering code complexity.

Bill
 
M

Marshall Barton

Bill said:
Yes, I'd already run into the conversion issue as I attempted
to formulate some sample code approaches.

Perhaps I'd have simpler looking code segments were I to
use an array approach? I.e., have 16 elements of type bit.
Thus, my originally posted example would look more like:

If bitI(8) = bitJ(8) then BLAH BLAH BLAH

This may all be for naught, as I'm restricted in table field-defs
to number-integer to create fields of length 16 bits and then
wouldn't that put me right back in the conversion problem
again?

Another approach would be to have 16 1-byte table fields
and reference them in code using Field-Collection notation.
Like, fld0; fld1; fld2;..........fld15 and reference as
FieldsCollection("fld" & MyIndex). This approach expands
a portion of four of my tables by a factor of eight, but perhaps
that's a small price to pay considering code complexity.


I don't understand the complexity. If the values are
already in Integer or Long fields, what's wrong with using:

Function GetBit(v As Integer, b As Integer) As Integer
GetBit = v \ 2 ^ b Mod 2
End Function

If the values are text strings of 1s and 0s:
GetBit = Left(Right(v, b), 1)
 
B

Bill

Marsh,
From your code, I gather that the statement:

GetBit = v \ 2 ^ b Mod 2

is obtaining the bit value in "b" that corresponds to
the same bit-position in "v". Thus, if the value of
"v" is 4096, then the function will either return
a value of 4096 or zero. Correct?

I've never seen the notation "\2^". Maybe I'd get
a clearer picture of what you're trying to teach me
if you could explain that.

As an aside, I always find it somewhat amusing to
look for VBA equivalents to what are primitive
elements of many mainframe languages.
Bill
 
D

Douglas J. Steele

No. "b" is the bit number in the number, v is the number.

\ is integer arithmetic: a \ b is the same as Int(a/b)

2 ^ b is 2 raised to the power of b

--
Doug Steele, Microsoft Access MVP

(no private e-mails, please)


Bill said:
Marsh,
From your code, I gather that the statement:

GetBit = v \ 2 ^ b Mod 2

is obtaining the bit value in "b" that corresponds to
the same bit-position in "v". Thus, if the value of
"v" is 4096, then the function will either return
a value of 4096 or zero. Correct?

I've never seen the notation "\2^". Maybe I'd get
a clearer picture of what you're trying to teach me
if you could explain that.

As an aside, I always find it somewhat amusing to
look for VBA equivalents to what are primitive
elements of many mainframe languages.
Bill
 
M

Marshall Barton

If v is the integer 4096, and b is 12, the function will
return 1. If v is 12287 and b is 12 the result is 0

The \ operator is integer division (e.g. 8 \ 3 is 2)

The ^ operator is exponent (e.g. 2 ^ 12 is 4096)
 
B

Bill

My brain must have been in left field to not have
deduced the ^ as the exponentiation operator. Here
again is "old language" hangover, as many other
languages use 2**12 to denote 2 to the 12th.

Thanks Doug & Marsh, I think I'm on my way now.

Bill


Marshall Barton said:
If v is the integer 4096, and b is 12, the function will
return 1. If v is 12287 and b is 12 the result is 0

The \ operator is integer division (e.g. 8 \ 3 is 2)

The ^ operator is exponent (e.g. 2 ^ 12 is 4096)
--
Marsh
MVP [MS Access]

Marsh,
From your code, I gather that the statement:

GetBit = v \ 2 ^ b Mod 2

is obtaining the bit value in "b" that corresponds to
the same bit-position in "v". Thus, if the value of
"v" is 4096, then the function will either return
a value of 4096 or zero. Correct?

I've never seen the notation "\2^". Maybe I'd get
a clearer picture of what you're trying to teach me
if you could explain that.
 
A

Albert D. Kallal

Yoy do realize that you can use "and" operations, and they are bit wise.

eg:


Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)


Sub bittest()

Dim b(1 To 2) As Byte
Dim c As Long

b(1) = &HFF
b(2) = &HFF

CopyMemory c, b(1), 2

Debug.Print c

End Sub

The above will output:
65535

and, note that if you stored the vlaeus as long, you could use the first 2
bytes as un-signed intergers.


bitI = 0000000010000000 = &h00 &h80 = 128
bitJ = 0001001010000001 = &h12 &h81 = 4737

debug.Print 4737 and 128
= 128

Note how the value returned is the 1 bit.... IF we move the bit one to the
left.then we have:

debug.Print 4737 and 256
= 0

So, no, we not forgot about the good old mainframe days..the problem is that
you have your data stored as strings when they should be stored as long
numbers (we do have to waste the first two byes because we unfortunately do
NOT have a un-signed integer type...


--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
[email protected]


Bill said:
My brain must have been in left field to not have
deduced the ^ as the exponentiation operator. Here
again is "old language" hangover, as many other
languages use 2**12 to denote 2 to the 12th.

Thanks Doug & Marsh, I think I'm on my way now.

Bill


Marshall Barton said:
If v is the integer 4096, and b is 12, the function will
return 1. If v is 12287 and b is 12 the result is 0

The \ operator is integer division (e.g. 8 \ 3 is 2)

The ^ operator is exponent (e.g. 2 ^ 12 is 4096)
--
Marsh
MVP [MS Access]

Marsh,
From your code, I gather that the statement:

GetBit = v \ 2 ^ b Mod 2

is obtaining the bit value in "b" that corresponds to
the same bit-position in "v". Thus, if the value of
"v" is 4096, then the function will either return
a value of 4096 or zero. Correct?

I've never seen the notation "\2^". Maybe I'd get
a clearer picture of what you're trying to teach me
if you could explain that.


Bill wrote:
Yes, I'd already run into the conversion issue as I attempted
to formulate some sample code approaches.

Perhaps I'd have simpler looking code segments were I to
use an array approach? I.e., have 16 elements of type bit.
Thus, my originally posted example would look more like:

If bitI(8) = bitJ(8) then BLAH BLAH BLAH

This may all be for naught, as I'm restricted in table field-defs
to number-integer to create fields of length 16 bits and then
wouldn't that put me right back in the conversion problem
again?

Another approach would be to have 16 1-byte table fields
and reference them in code using Field-Collection notation.
Like, fld0; fld1; fld2;..........fld15 and reference as
FieldsCollection("fld" & MyIndex). This approach expands
a portion of four of my tables by a factor of eight, but perhaps
that's a small price to pay considering code complexity.


I don't understand the complexity. If the values are
already in Integer or Long fields, what's wrong with using:

Function GetBit(v As Integer, b As Integer) As Integer
GetBit = v \ 2 ^ b Mod 2
End Function

If the values are text strings of 1s and 0s:
GetBit = Left(Right(v, b), 1)
 
Top