[SOLVED] Returning a specific bit of a byte value

Just starting out? Need help? Post your questions and find answers here.
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

[SOLVED] Returning a specific bit of a byte value

Post by Oso »

Hello all. Is there an uncomplicated way to return a specific bit of a byte, for example where I'm using the below bits to denote functions?

Code: Select all

mode.b + %0001                   ; Print (yes)
mode.b + %0010                   ; Suppress key value (yes)
mode.b + %0100                   ; Totals only (yes)
How can I say, If Bit2 = #True then do 'x'?
Last edited by Oso on Mon Jan 30, 2023 7:36 pm, edited 1 time in total.
User avatar
yuki
Enthusiast
Enthusiast
Posts: 101
Joined: Sat Mar 31, 2018 9:09 pm

Re: Returning a specific bit of a byte value

Post by yuki »

Classic bitmasking.

Code: Select all

Define mode.b
mode | %0001                   ; Print (yes)
mode | %0010                   ; Suppress key value (yes)
mode | %0100                   ; Totals only (yes)

; Perform a binary AND with %010 to extract only bits in `mode` which match the ON (1) bits in %010.
If mode & %010
  Debug "Suppress key value on!"
EndIf
See also EnumerationBinary, which can be useful to autogenerate these flag values. E.g.:

Code: Select all

EnumerationBinary
  #ModePrint
  #ModeSuppressKeyValue
  #ModeShowTotalsOnly
EndEnumeration
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Returning a specific bit of a byte value

Post by Oso »

yuki wrote: Sun Jan 29, 2023 7:21 am Classic bitmasking.

Code: Select all

Define mode.b
mode | %0001                   ; Print (yes)
mode | %0010                   ; Suppress key value (yes)
mode | %0100                   ; Totals only (yes)
Thank you yuki that's great, very convenient to perform the check too. :) I like the setting of the mode with OR as you've done above.
User avatar
yuki
Enthusiast
Enthusiast
Posts: 101
Joined: Sat Mar 31, 2018 9:09 pm

Re: Returning a specific bit of a byte value

Post by yuki »

Oso wrote: Sun Jan 29, 2023 7:33 am
yuki wrote: Sun Jan 29, 2023 7:21 am Classic bitmasking.

Code: Select all

Define mode.b
mode | %0001                   ; Print (yes)
mode | %0010                   ; Suppress key value (yes)
mode | %0100                   ; Totals only (yes)
Thank you yuki that's great, very convenient to perform the check too. :) I like the setting of the mode with OR as you've done above.
Glad to be of help! :)

And yeah, using OR to apply the flags is handy since it can prevent gotchas when accidentally reapplying them, e.g.:

Code: Select all

mode + #ModePrint + #ModePrint + #ModeSuppressKeyValue
In which case mode ends up as %100 instead of %011. Whereas replacing "+" with "|" we've the usual %011.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Returning a specific bit of a byte value

Post by infratec »

Thre are several examples in Tips 'n' Tricks.

You can also use a Macro:

Code: Select all

Macro IsBitNoXSet(Value, Bit)
  Bool(Value & (1 << Bit))
EndMacro

Macro IsBitMaskBitSet(Value, Mask)
  Bool(Value & Mask)
EndMacro


Define.u Word

Word = %1001000100100100

Debug IsBitNoXSet(Word, 0)
Debug IsBitNoXSet(Word, 2)

If IsBitNoXSet(Word, 14)
  Debug "Bit 14 is set"
Else
  Debug "Bit 14 is not set"
EndIf

If IsBitNoXSet(Word, 15)
  Debug "Bit 15 is set"
Else
  Debug "Bit 15 is not set"
EndIf

If IsBitMaskBitSet(Word, %0100000000000000)
  Debug "Bit 14 is set"
Else
  Debug "Bit 14 is not set"
EndIf

If IsBitMaskBitSet(Word, %1000000000000000)
  Debug "Bit 15 is set"
Else
  Debug "Bit 15 is not set"
EndIf
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Returning a specific bit of a byte value

Post by Oso »

infratec wrote: Sun Jan 29, 2023 9:59 am Thre are several examples in Tips 'n' Tricks. You can also use a Macro:

Code: Select all

Macro IsBitNoXSet(Value, Bit)
  Bool(Value & (1 << Bit))
EndMacro
Thanks infratec, I experimented for at least a couple of hours with a bit shift as you've done before even posting the question on the forum yesterday but there had been a bug in my testing, leading me to conclude that it couldn't be done this way. The bug was that I was assuming the first bit was bit 1, rather than bit 0, so my results were unpredictable. :D Thanks for sending this.
highend
Enthusiast
Enthusiast
Posts: 123
Joined: Tue Jun 17, 2014 4:49 pm

Re: [SOLVED] Returning a specific bit of a byte value

Post by highend »

I guess I'll solve this by creating a new map Bits() with all the necessary values as the key and the value is the x position of the bit it belongs to.
Then I can query that map via FindMapElement() and then feed the bit testing procedure with the necessary bit position...


Is it also possible to check if a "bit value" is present?

E.g. the value to check is 12.
The used "bit values" are 4 and 8.

Code: Select all

This should be the result:
Debug Bool(12 & 1) => #False
Debug Bool(12 & 2) => #False
Debug Bool(12 & 4) => #True
Debug Bool(12 & 8) => #True
Debug Bool(12 & 16) => #False
I need to read a foreign .ini file and it is has key - value pairs like this (for bitmask entries)
and a lot of them miss out values. Additionally they need to retain their order...

Code: Select all

[Save_Changes_To_Disk]
2 = Catalog
1 = Configuration
2048 = Favorites
32 = Folder View Settings
8 = Keyboard Shortcuts
4096 = Tabs
64 = Tags
4 = User-Defined Commands
I'm storing these entries in a structured list and it would be cool if I can check them in their order of appearance...
Post Reply