Check for Bit 1001

kirkm

Registered User.
Local time
Tomorrow, 01:04
Joined
Oct 30, 2008
Messages
1,257
Whats the correct way to tell if a byte = xxxx1001 ?
 
what do you mean?

1001 = 9(dec)

so you And the number with 9, eg:
let X, any number

X And 9 = 9 (result should be 9)
 
let X, any number

X And 9 = 9 (result should be 9)
Am I misunderstanding you?
Code:
X=27
debug.print X AND 9
the result is 9
27 in binary is 11011.

Code:
X=59
debug.print X AND 9
Again the result is 9.
59 in binary is 111011

I think any number that is ending in 1011 will return 9.
 
Last edited:
I think you need a function to check it.

Code:
'https://www.codegrepper.com/code-examples/vb/excel+vba+convert+number+to+binary+string
Function DecToBin$(ByVal n&)
    Do
        DecToBin = n Mod 2 & DecToBin
        n = n \ 2
    Loop While n
End Function

then you can check :

Code:
IF DecToBin(9)= 1001 then 
   .....
end if
 
Thanks for the replies. Understood and getting there now.
 
almost.

you need to Format() and Extract the 4th Rightmost digit:

If Right$(Format$(DecToBin(X), "000000000000"), 4) = "1001" Then
...
End If
 
Something like:

Code:
Dim IsNine As Boolean
...
IsNine = ( ( X AND &h0F ) = 9 )
 
This page has an example of how they are typically used to compare two values and a bit (no pun intended) of an explanation at the bottom of the code.
 
Bitwise allows the independent comparison of the individual bits in one operation.

The result of X AND Y is 1 for bits that are 1 in both X and Y.

&h0F is hexadecimal notation for the decimal value 15 which is 1111.

Thus 9 AND 15 = 9
This is a trivial test but variations with the other bitwise operators can do addition and subtraction of the individual bits or make comparisons. This is the basis for logic in computing.
 
see Post #1, it is not about "9".
its about determining if a number has 4 bits, 1001 at the End.
 
if you want specifically to test for 1001 and 9, and 9 only, then do you want 11, 13, and 15 to fail?
In which case "and"ing with 9 is not sufficient, since 11 and 9 will also return 9.

So 1001 is 9
1011 is is 11
1101 is 13
1111 is 15

all of these return 9 when "and" ing with 9. If you want to test that only bits 5 and 8 are set it's not so easy.

xor will work for values from 1 to 15, but won't work for values with the large bits set.
mynumber xor 9 = 0 tests for 9 and only 9. (ie 1001)

But it doesn't deal with higher order bits - so for instance 73 (which is 64+9) doesn't work
73 xor 9 = 64 and
73 xor 11 = 66

so this expression tests whether the last 4 bits are 1001, and ignores the other bits, but I am having to subtract whatever the value of the first 4 bits represents.

MsgBox (((mynumber - (mynumber And 240)) Xor 9) = 0)

I can't see a simpler bitwise trick to ignore bits 1 to 4.

yes, I can now.
msgbox ((mynumber and 15) = 9)

(edit - and now I also see that @The_Doc_Man and @Galaxiom also mentioned this solution)



 
Last edited:
The_Doc_Man, can you elaborate on this? I can't understand how it works.
Thank you.

Sure. Doing a logical AND is a type of bit-masking, i.e. taking out bits you didn't want to see but retaining the ones you DID want to see.

The value &h0F is a hexadecimal constant that says "give me four leading zero bits followed by hexadecimal F" which in binary is 00001111. I wrote it that way so that if the constant had to be expanded from 8 bits to 16 or 32 (or even 64) bits, it would expand correctly to 0000...00001111. I could have written that as 15 (the decimal equivalent) but since bit-masking was involved, I used hexadecimal. It is easier to see what was intended when I do it that way.

The (bit-wise) AND operator says give me a 1-bit in every bit position where there is a 1 in BOTH corresponding bit positions for the inputs. So all those leading zeros REMOVE all the bits other than the low-order four bits from the input variable X. What will be left will be a string of 0 bits plus the string of bits that were originally in the low-order four bits of X. The "F" acts like a pass-thru filter for those four bits.

The OP's question was "Whats the correct way to tell if a byte = xxxx1001 ?" So obviously, @kirkm doesn't care about the xxxx part, just the lowest four bits of the number. Thus, ( X AND &h0F ) gives him the lowest four bits of the number. IF the desire is to see if those bits are hexadecimal 9, then ( X AND &h0F ) = 9 will be a true/false "relational math" expression.
 
@The_Doc_Man
I couldn't understand why you chose &h0F(15). But your detailed explanation cleared it.
I appreciate taking your time and explain it that simple.
 
That is all great info and rings bells from long ago. I did get things back to front though and find I actually need the first 4 bits (is that the high nibble?). It might be that (X and &hF0) gives that, but I'm not sure. Now I get out of my depth.. I need to read in 2.5 bytes in "Big Endian" format from a file.
They are (in Hex) OA C4 40. If I put that into my calculator as Hex AC44 and hit the DEC button I get 44100 which is correct. Another example is 17 70 03. That = 96000 (you need the '0' from 03 but not the '3'). While my calculator is great I'm not sure how best to code this in VBA. Each byte is decimal. So I have
Code:
Dim x as string * 3
get # myfile, OffsetPos,x
For y= 1 to 3 :Debug.Print " "; Format(Hex(Asc(Mid(x, y))), "0#");:next
Than I could stringslice that and use a Hex-Dec conversion.
But I think that is a totally wrong approach. Be interested how others might do it.
 
It might be that (X and &hF0) gives that, but I'm not sure.

If so, it now depends on the size of X. If X is BYTE then &HF0 does, indeed give you that high "nibble" - but you cannot compare to 9 now. You have to compare to &H90 - or you could divide by a power of 2 to shift the bits. Also, since 9 in hex is 1001, that puts a 1 in the sign bit, so the order of the operation is significant. Unfortunately, though VB has a bit-shift operator, VBA does not. So we have to "fake it."

Suppose that you have X as a WORD (i.e. 16-bit) integer. Then the operation would look like this:

Code:
BitOfInterest = &H1000            'low-order bit of high-order nibble.
IsNine = ( ( ( X / BitOfInterest ) AND &H000F ) = 9 )

The order of this operation is crucial. If you do the masking BEFORE you do the shift, you will not get &H0009; you will get &HFFF9 because of sign-bit shifting.
 
I need to read in 2.5 bytes in "Big Endian" format from a file.
They are (in Hex) OA C4 40

The problem is being sure of which byte is which. If you use a LONG integer, you can do something that might look like this, assuming the bytes are presented in the wrong order. (And by the way, are you saying that you are "unpacking 5-nibble sequences? Your examples don't make sense otherwise.)

Code:
DIM B1 As Long, B2 As Long, B3 As Long, BX as Long
B1 = CLNG( 1st byte )
B2 = CLNG( 2nd byte )
B3 = CLNG( 3rd byte )
'   at this point, either B1 or B3 will have to then be bit-masked and (maybe) bit-shifted
BX = B1 OR ( B2 * 256 ) OR (  B3 * 65536 )

The confusion is that your example appears to take the bytes apart inconsistently.
 
I'm probably not describing this too well.. I suppose it is "5 nibbles" as I tried to show by "2.5 bytes".
Looking at the file with a disk editor there are three bytes 0A C4 40.
From this I want a string "AC44". Then ? clng("&hac44") gives the correct result.
However the values read from disk are decimal. So do I construct this "hex" from them or use a different method to work with the decimal numbers directly? Or maybe something entirely different ? (As you can guess I'm no maths guru and these calculations are hard for me.)
 
The bitwise operators should work on any integers however they are expressed.
 

Users who are viewing this thread

Back
Top Bottom