Ian Branch 128 Posted January 21, 2019 Hi Team, I am playing around with testing if a bit is set in a byte, or not. I can run the follow pseudo code to say test bits 1, 3 & 7 without issue.. "If Bitset(0) or Bitset(3) or BitSet(7) then do something.." It will be a random test byte value being compared to the reference byte. My question is - Is there an easier way to do this type of thing? Regards & TIA, Ian Share this post Link to post
Kryvich 165 Posted January 22, 2019 (edited) You can write it as If ((b and $01) > 0) or ((b and $08) > 0) or ((b and $80) > 0) then ... Or you can create an enumeration and use meaningful names for each bit. type TMyEnum = (mb0, mb1, mb2, mb3, mb4, mb5, mb6, mb7); TMyBits = set of TMyEnum; // = Byte in size function Test: Byte; var mbs: TMyBits; begin mbs := [mb0, mb3, mb7]; Byte(mbs) := $89; // It's equivalent of mbs := [mb0, mb3, mb7]; if mbs * [mb0, mb3, mb7] <> [] then // If one of bit is set ;//... if mbs * [mb0, mb3, mb7] = [mb0, mb3, mb7] then // If all 3 bits are set ;//... if mbs - [mb0, mb3, mb7] = [] then // If no other bits are set ;//... Include(mbs, mb1); // Set 2nd bit mbs := mbs - [mb3, mb7]; // Unset 4th and 8th bit //etc... Result := Byte(mbs); end; It's always better to deal with clearly named typed variables and constants. Edited January 22, 2019 by Kryvich 4 Share this post Link to post
haentschman 92 Posted January 22, 2019 Quote enumeration and use meaningful names I have an old project in maintenance. This is full of bit operations. If you don't work with it permanently, you want meaningful names. 1 Share this post Link to post
Ian Branch 128 Posted January 22, 2019 Hi Kryvich, Interesting approach. I shall have a play. Regards, Ian Share this post Link to post
Kryvich 165 Posted January 22, 2019 @haentschman It's always better to have named constants instead of numbers. Say you want to swap 2nd and 6th bits in some structure's field. Then you need to scan all your program and check all places where these bits are used. But if you used an enumeration from the start, you just swap these bits in the declaration: type TMyEnum = (mb0, mb5, mb2, mb3, mb4, mb1, mb6, mb7); Of course instead of mb0, mb1 etc. should be really meaningful names, without numbers. 1 Share this post Link to post
haentschman 92 Posted January 22, 2019 (edited) @Kryvich You miss understand. I aggree with you... I am a fan of Enumerations. Better: If you MUST work with it permanently, you want meaningful names. Sorry. Edited January 22, 2019 by haentschman 1 Share this post Link to post
Der schöne Günther 316 Posted January 22, 2019 I always found using System.Classes.TBits easier to use than raw bit operations... if myValue.Bits[3] then (...) 1 Share this post Link to post
Ian Branch 128 Posted January 22, 2019 Hmm. I like the 'Bits' concept, never used it/them. Not good for readability though. Share this post Link to post
David Heffernan 2353 Posted January 22, 2019 Ugh, a class allocated on dynamic memory just to do bit twiddling. What is so hard about the and operator? Share this post Link to post
Rollo62 539 Posted January 23, 2019 10 hours ago, David Heffernan said: Ugh, a class allocated on dynamic memory just to do bit twiddling. What is so hard about the and operator? Quote Use TBits to store and access an indefinite number of Boolean values. Whoever needs this ... Share this post Link to post
David Heffernan 2353 Posted January 23, 2019 9 hours ago, Rollo62 said: Whoever needs this ... But this topic concerns the 8 bits in a byte. Share this post Link to post
Rollo62 539 Posted January 23, 2019 Oooh yes, you're right. Just checked the headline Then I hope that someone still finds the info about such alternative (system) method interesting, with all pro's and con's. 9 minutes ago, David Heffernan said: But this topic concerns the 8 bits in a byte. Share this post Link to post
Rudy Velthuis 91 Posted February 11, 2019 On 1/22/2019 at 10:38 AM, Der schöne Günther said: I always found using System.Classes.TBits easier to use than raw bit operations... if myValue.Bits[3] then (...) TBits is in fact a bitset. Works well, but a bit overblown if you can easily use a Pascal set, which is far more lightweight (and faster), especially if you have less than 32 items (bits). Share this post Link to post
Rudy Velthuis 91 Posted February 11, 2019 (edited) On 1/22/2019 at 12:33 AM, Ian Branch said: Hi Team, I am playing around with testing if a bit is set in a byte, or not. I can run the follow pseudo code to say test bits 1, 3 & 7 without issue.. "If Bitset(0) or Bitset(3) or BitSet(7) then do something.." It will be a random test byte value being compared to the reference byte. My question is - Is there an easier way to do this type of thing? Regards & TIA, Ian If you have the choice, use a Pascal set, as described by others. If you don't have that luxury (e.g. because your code must be compatible with other languages, e.g. when you are writing a DLL or some such), you can do: const Bit0 = 1 shl 0; // or more meaningful names Bit1 = 1 shl 1; ... Bit7 = 1 shl 7; ... Bits_0_3_7 = Bit0 or Bit3 or Bit7; ... if (Value and Bits_0_3_7) <> 0 then ... // equivalent to "or" if (Value and Bits_0_3_7) = Bits_0_3_7 then ... // equivalent to "and" That is a little less convenient, but compatible with C and how most APIs do this. You should of course give the bits and the combinations more meaningful names. Edited February 11, 2019 by Rudy Velthuis Share this post Link to post