Results 1 to 22 of 22

Thread: [RESOLVED] Boolean or Byte or Bit ?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Resolved [RESOLVED] Boolean or Byte or Bit ?

    I need to define some UDTs like:
    Code:
    Type Elem_Options
        Option1 As Boolean
        Option2 As Boolean
        Option3 As Boolean
        Option4 As Boolean
        Option5 As Boolean
        Option6 As Boolean
        Option7 As Boolean
        Option8 As Boolean
        Option9 As Boolean
        Option10 As Boolean
        Option11 As Boolean
        Option12 As Boolean
        Option13 As Boolean
        Option14 As Boolean
    End Type
    
    Private m_ElemOptions(1000000) As Elem_Options
    Elem_Options needs to occupy 28 bytes. If I change Boolean to Byte, Elem_Options only need to occupy 14 bytes:
    Code:
    Type MyOptions
        Option1 As Byte
        Option2 As Byte
        Option3 As Byte
        Option4 As Byte
        Option5 As Byte
        Option6 As Byte
        Option7 As Byte
        Option8 As Byte
        Option9 As Byte
        Option10 As Byte
        Option11 As Byte
        Option12 As Byte
        Option13 As Byte
        Option14 As Byte
    End Type
    
    Private m_ElemOptions(1000000) As Elem_Options
    I'd like to know the advantages and disadvantages of the above two methods. After changing Boolean to Byte, will it affect the performance of the software? Thanks !

    Also, is it necessary to change Byte to Bit?

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,261

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by SearchingDataOnly View Post
    I need to define some UDTs like:

    I'd like to know the advantages and disadvantages of the above two methods. After changing Boolean to Byte, will it affect the performance of the software? Thanks !

    Also, is it necessary to change Byte to Bit?
    Advantage: Less memory used
    Disadvantage: Not intuitive for reading code nevermind implicit TypeCast/-Conversion might run havoc and hide Bugs

    I wouldn't know of a BIT-DataType.....

    The way i would do it:
    If you need 14 Booleans (True/False), you would need 14 Bits, which rounds up to 16 Bits, which is 2 Bytes, which corresponds with 2-Byte Integer, and do it via masking
    e.g.
    The integer-value "3" is binary "0000 0000 0000 0011"
    So, to check if Option2 is set you just do a
    "If MyOptionInteger And 2 Then Debug.Print "Option2 is True"
    Or for Option4
    "If MyOptionInteger And 8 Then Debug.Print "Option4 is False"

    So, where you take 14/28 Bytes, i take 2
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Boolean or Byte or Bit ?

    If you really need it dimmed to a million, I'd tend to write some procedures for setting and checking bits. That'd reduce your memory needs by a factor of 8 over Bytes and a factor of 16 over Booleans.

    Just as an FYI, Booleans are just a special case of Integers (which are two bytes), although the compiler and the runtime engine try to keep them as either 0 or -1, but not always.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  4. #4
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Boolean or Byte or Bit ?

    Boolean, as mentioned by Elroy, would be 2 bytes per value. 14 values is 28b per, and if you're planning to have 1m of these it'll take up 28MB of memory.

    If you chose Byte, it'd be 1 byte per value so that's 14MB.

    If, as mentioned, you set up a function that took a value and returned the value of that point (or set the value) you would use about 1.75MB...a fraction of the above. I'm sure you can work out ways to do it with a byte array storing the relative values, it's not too difficult.

    If memory is your only requirement (which you haven't specified) the byte array referencing function would definitely perform the best...surprisingly, there are ways in which you could take things even further by compressing the bit data (I had a tree method for compressing weighted bit streams of data that has very few 1s...complicated stuff :-))...it's adding more processing but reducing memory overheads.

    If you're looking for speed over memory, I would think byte is best as it's only one byte (rather than two) and takes less time to access...worth testing if you were that worried about the potential speed issues.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    Re: Boolean or Byte or Bit ?

    Does it take less time to access? I don't know how VB6 accesses data, but I don't think there is any advantage to shifting one byte into a register. I'm not even sure it's truly possible, which is probably why a Boolean is taking two bytes when it technically only needs a single bit.
    My usual boring signature: Nothing

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Shaggy Hiker View Post
    Does it take less time to access? I don't know how VB6 accesses data, but I don't think there is any advantage to shifting one byte into a register. I'm not even sure it's truly possible, which is probably why a Boolean is taking two bytes when it technically only needs a single bit.
    That's actually a good point. I haven't tested, but it might actually take more time to test a Byte than to test a Boolean. If it's forced to use a 16-bit register (which I'd suspect it is), with a Byte, it's going to load the next byte so it'll need to zero it out (or maybe there are 8-bit tests). With a Boolean (two bytes), it can just load and test, no zeroing needed.

    EDIT: Actually, it's been a while since I've messed with assembly, but I just looked at the Pentium instruction set, and there are 8-bit move instructions, so maybe a Byte would be a couple of ticks faster.
    Last edited by Elroy; Mar 10th, 2022 at 07:07 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Boolean or Byte or Bit ?

    I suppose there is always RtlInitializeBitMap and friends. Using a typlib should shave a little overhead.

    Remarks

    A driver can use a bitmap variable as an economical way to keep track of a set of reusable items. For example, file systems use a bitmap variable to track which clusters/sectors on a disk have already been allocated to hold file data. The system-supplied SCSI port driver uses a bitmap variable to track which queue tags have been assigned to SCSI request blocks (SRBs).
    These work in normal user programs as well as drivers.

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Zvoni View Post
    Advantage: Less memory used
    Disadvantage: Not intuitive for reading code nevermind implicit TypeCast/-Conversion might run havoc and hide Bugs

    I wouldn't know of a BIT-DataType.....

    The way i would do it:
    If you need 14 Booleans (True/False), you would need 14 Bits, which rounds up to 16 Bits, which is 2 Bytes, which corresponds with 2-Byte Integer, and do it via masking
    e.g.
    The integer-value "3" is binary "0000 0000 0000 0011"
    So, to check if Option2 is set you just do a
    "If MyOptionInteger And 2 Then Debug.Print "Option2 is True"
    Or for Option4
    "If MyOptionInteger And 8 Then Debug.Print "Option4 is False"

    So, where you take 14/28 Bytes, i take 2
    Quote Originally Posted by Elroy View Post
    If you really need it dimmed to a million, I'd tend to write some procedures for setting and checking bits. That'd reduce your memory needs by a factor of 8 over Bytes and a factor of 16 over Booleans.

    Just as an FYI, Booleans are just a special case of Integers (which are two bytes), although the compiler and the runtime engine try to keep them as either 0 or -1, but not always.

    Quote Originally Posted by SmUX2k View Post
    Boolean, as mentioned by Elroy, would be 2 bytes per value. 14 values is 28b per, and if you're planning to have 1m of these it'll take up 28MB of memory.

    If you chose Byte, it'd be 1 byte per value so that's 14MB.

    If, as mentioned, you set up a function that took a value and returned the value of that point (or set the value) you would use about 1.75MB...a fraction of the above. I'm sure you can work out ways to do it with a byte array storing the relative values, it's not too difficult.

    If memory is your only requirement (which you haven't specified) the byte array referencing function would definitely perform the best...surprisingly, there are ways in which you could take things even further by compressing the bit data (I had a tree method for compressing weighted bit streams of data that has very few 1s...complicated stuff :-))...it's adding more processing but reducing memory overheads.

    If you're looking for speed over memory, I would think byte is best as it's only one byte (rather than two) and takes less time to access...worth testing if you were that worried about the potential speed issues.
    Yes, using Bit seems to be the better approach, although it requires more code to be written. I plan to use "Dim BitArray(1) As Byte" to hold 16 Bits. Thanks Zvoni, Elroy and SmUX2k.

  9. #9

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Shaggy Hiker View Post
    Does it take less time to access? I don't know how VB6 accesses data, but I don't think there is any advantage to shifting one byte into a register. I'm not even sure it's truly possible, which is probably why a Boolean is taking two bytes when it technically only needs a single bit.
    Quote Originally Posted by Elroy View Post
    That's actually a good point. I haven't tested, but it might actually take more time to test a Byte than to test a Boolean. If it's forced to use a 16-bit register (which I'd suspect it is), with a Byte, it's going to load the next byte so it'll need to zero it out (or maybe there are 8-bit tests). With a Boolean (two bytes), it can just load and test, no zeroing needed.

    EDIT: Actually, it's been a while since I've messed with assembly, but I just looked at the Pentium instruction set, and there are 8-bit move instructions, so maybe a Byte would be a couple of ticks faster.
    Yes, I've heard a point before that using Long is faster than Integer, maybe because of the registers. This is also why I worry that Byte is slower than Boolean. Thank you, Shaggy Hiker and Elroy.
    Last edited by SearchingDataOnly; Mar 11th, 2022 at 06:47 AM.

  10. #10

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by dilettante View Post
    I suppose there is always RtlInitializeBitMap and friends. Using a typlib should shave a little overhead.



    These work in normal user programs as well as drivers.
    This is a very attractive proposition. It would be better if there is a simple example to demonstrate how to use RtlInitializeBitMap to store multiple Bits. Thank you, dilettante.

  11. #11
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by SearchingDataOnly View Post
    Yes, using Bit seems to be the better approach, although it requires more code to be written. I plan to use "Dim BitArray(1) As Byte" to hold 16 Bits. Thanks Zvoni, Elroy and SmUX2k.
    If you want to use 2 bytes like that, the integer datatype has the value -32768 to 32767 (so a total of 65536) and uses only 2 bytes. It does require that you shift the value by 32768 into another variable before you do the bit checking so it may be extra processing, but it would mean that you could have one huge integer array that stored all the bits and can easily be referenced by number. Another option is a unicode string (which uses 2 bytes per character), but that's not going to be much different to integer and will also require extra processing.

    If speed is of importance, you may have to stress-test different options to see which is fastest in your case...it's often something I don't worry too much about as the miniscule differences in speed don't usually affect my code (or at least it doesn't have enough of an effect to bother me). If memory is highest importance, the integer datatype is probably going to be best though not considerably better than the byte option.

  12. #12

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by SmUX2k View Post
    If you want to use 2 bytes like that, the integer datatype has the value -32768 to 32767 (so a total of 65536) and uses only 2 bytes. It does require that you shift the value by 32768 into another variable before you do the bit checking so it may be extra processing, but it would mean that you could have one huge integer array that stored all the bits and can easily be referenced by number. Another option is a unicode string (which uses 2 bytes per character), but that's not going to be much different to integer and will also require extra processing.

    If speed is of importance, you may have to stress-test different options to see which is fastest in your case...it's often something I don't worry too much about as the miniscule differences in speed don't usually affect my code (or at least it doesn't have enough of an effect to bother me). If memory is highest importance, the integer datatype is probably going to be best though not considerably better than the byte option.
    The reason why I use "Dim BitArray(1) As Byte" is to be able to expand to BitArray(2) or BitArray(3) in the future. In fact, Long (4 bytes) saves 32 bits, which is enough to meet my future expansion needs. But I don't know how to do Bit operations on Long yet.

  13. #13
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    Re: Boolean or Byte or Bit ?

    Code:
    Option Explicit
    
    Private m_Bits(31) As Long
    
    Public Sub InitBits()
      Dim i As Long, lBits As Long
      
      lBits = 1
      For i = 0 To 30
        m_Bits(i) = lValue
        If i < 30 Then lBits = lBits * 2
      Next i
      m_Bits(31) = -2147483648#
    End Sub
    
    Public Sub SetBit(lValue As Long, ByVal lIndex As Long)
    '  Sets indicated bit to one, or ON.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31&
      
      lValue(indx) = lValue(indx) Or m_Bits(ofst)  'turn the bit ON
    End Sub
    
    Public Function GetBit(lValue As Long, ByVal lIndex As Long) As Long
    ' Returns zero if the indicated bit is off, NON-ZERO if on.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31& 'posn MOD 32
      
      GetBit = lValue And m_Bits(ofst)
    End Function
    
    Public Function IsBitSet(lValue As Long, ByVal lIndex As Long) As Boolean
    ' Returns zero if the indicated bit is off, NON-ZERO if on.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31& 'posn MOD 32
      
      IsBitSet = (lValue And m_Bits(ofst)) <> 0
    End Function
    
    Public Sub ClearBit(lValue As Long, ByVal posn As Long)
    ' Sets indicated bit to zero, or OFF.
      Dim indx As Long, ofst As Long
      
      indx = posn \ 32
      ofst = posn And 31 ' BITS0thru4 ' posn MOD 32
      
      lValue = lValue And (Not m_Bits(ofst)) 'turn the bit OFF
    End Sub
    
    Public Function CountBits(lValue As Long) As Long
      Dim lValue As Long
      
      If lValue Then
        If lValue = -1 Then
          CountBits = CountBits + 32
        Else
          If lValue And &H1 Then CountBits = CountBits + 1
          If lValue And &H2 Then CountBits = CountBits + 1
          If lValue And &H4 Then CountBits = CountBits + 1
          If lValue And &H8 Then CountBits = CountBits + 1
          If lValue And &H10& Then CountBits = CountBits + 1
          If lValue And &H20& Then CountBits = CountBits + 1
          If lValue And &H40& Then CountBits = CountBits + 1
          If lValue And &H80& Then CountBits = CountBits + 1
          If lValue And &H100& Then CountBits = CountBits + 1
          If lValue And &H200& Then CountBits = CountBits + 1
          If lValue And &H400& Then CountBits = CountBits + 1
          If lValue And &H800& Then CountBits = CountBits + 1
          If lValue And &H1000& Then CountBits = CountBits + 1
          If lValue And &H2000& Then CountBits = CountBits + 1
          If lValue And &H4000& Then CountBits = CountBits + 1
          If lValue And &H8000& Then CountBits = CountBits + 1
          If lValue And &H10000 Then CountBits = CountBits + 1
          If lValue And &H20000 Then CountBits = CountBits + 1
          If lValue And &H40000 Then CountBits = CountBits + 1
          If lValue And &H80000 Then CountBits = CountBits + 1
          If lValue And &H100000 Then CountBits = CountBits + 1
          If lValue And &H200000 Then CountBits = CountBits + 1
          If lValue And &H400000 Then CountBits = CountBits + 1
          If lValue And &H800000 Then CountBits = CountBits + 1
          If lValue And &H1000000 Then CountBits = CountBits + 1
          If lValue And &H2000000 Then CountBits = CountBits + 1
          If lValue And &H4000000 Then CountBits = CountBits + 1
          If lValue And &H8000000 Then CountBits = CountBits + 1
          If lValue And &H10000000 Then CountBits = CountBits + 1
          If lValue And &H20000000 Then CountBits = CountBits + 1
          If lValue And &H40000000 Then CountBits = CountBits + 1
          If lValue And &H80000000 Then CountBits = CountBits + 1
        End If
      End If
      
    End Function
    Last edited by Arnoutdv; Mar 11th, 2022 at 08:05 AM.

  14. #14
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by SearchingDataOnly View Post
    The reason why I use "Dim BitArray(1) As Byte" is to be able to expand to BitArray(2) or BitArray(3) in the future. In fact, Long (4 bytes) saves 32 bits, which is enough to meet my future expansion needs. But I don't know how to do Bit operations on Long yet.
    If you used 2 integer arrays (or a 2-dimensional array?) you would have that option, you just use the first array as the lower bits (1-16) and the second arrays as the higher bits (17-32). If you wanted to reduce the overheads you could use the byte datatype and expand it from 2 to 3 when you need the third level of 8 and 3 to 4 when you need that last level of 8.

    Me, I would go with the byte option if I knew I had potential for needing expansion and wanted to minimise the overheads.

    So if you needed 1m positions and wanted to support up to 32 bits, you would use Dim BitArray(3,1000000) As Byte if you chose to use multidimensional array). If you do a bitcheck on BitArray(0,1) it would give results for the first 8 bits of the first value, a bitcheck on BitArray(1,1) would give results for the next 8, etc.

    All you need is a function that simplifies this by taking a value for the bit point you're after and the position in the array you want and does the calculations for where to look and returning the result, as in BitAt(1,100) (just an example name, it needs to be coded :-P) which would return the 1st bit value in the 100th number...I could probably write something in about 5 minutes that would do it, and just sits in a module waiting to be called. The usefulness of this is that if you needed (at design time) to raise the number of bits you could easily do it by adding to the bit portion of the variable.

    Using a Long would seem overly processor intensive to me, as you would need to check 2^point and with Longs that becomes a huge number...keeping it to bytes (or integers) simplifies things in some ways

  15. #15
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Boolean or Byte or Bit ?

    Very quick bit of code that seems to work for me, and much smaller than the one offered above:
    Code:
    Public BitArray(3, 1000000) As Byte
    
    Public Function getbit(point As Single, loc As Double)
    arrloc = 0: temppoint = point
    Do While temppoint > 8 'Gets the position along the dimensions
        temppoint = temppoint - 8: arrloc = arrloc + 1
        Loop
    getbit = BitArray(arrloc, loc) And 2 ^ (temppoint - 1)
    End Function
    
    Public Function setbit(point As Single, loc As Double, valu As Boolean)
    arrloc = 0: temppoint = point
    Do While temppoint > 8
        temppoint = temppoint - 8: arrloc = arrloc + 1
        Loop
    pos = BitArray(arrloc, loc) And 2 ^ (temppoint - 1)
    If pos = 0 And valu = True Then BitArray(arrloc, loc) = BitArray(arrloc, loc) + 2 ^ (temppoint - 1)
    If pos <> 0 And valu = False Then BitArray(arrloc, loc) = BitArray(arrloc, loc) - 2 ^ (temppoint - 1)
    setbit = getbit(point, loc)
    End Function
    getbit() pulls the value from the array as either zero (false) or non-zero (true)
    setbit() takes a true or false and places it at the designated location

    setbit(8, 100, True) Sets the 8th bit of the 100th value to true

    getbit(8, 100) pulls the value out (as zero or nonzero...shouldn't be difficult to have the output as boolean true or false)

    setbit(8, 100, False) Sets the same bit to false

    It isn't clean code, my code is generally function over form, but it's something that could be worked on from to get what you need...and yeah, took a little longer than 5 minutes but I haven't worked with the bit level in ages :-)
    Last edited by SmUX2k; Mar 11th, 2022 at 08:59 AM.

  16. #16
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Boolean or Byte or Bit ?

    Goodness gracious. That above code is doing implicit type casting all over the place, even to Doubles and back. I don't think that's what you want at all!

    If we're dealing with bits in Bytes, here's some code I just hammered out (not even tested, but it should work):

    Code:
    
    Option Explicit
    
    Public Property Get BitInByte(ByRef TheByte As Byte, ByVal Pos1to8 As Long) As Boolean
        ' Returns false if Pos1to8 is out of range.
        Select Case Pos1to8
        Case 1&:    BitInByte = TheByte And CByte(1)
        Case 2&:    BitInByte = TheByte And CByte(2)
        Case 3&:    BitInByte = TheByte And CByte(4)
        Case 4&:    BitInByte = TheByte And CByte(8)
        Case 5&:    BitInByte = TheByte And CByte(16)
        Case 6&:    BitInByte = TheByte And CByte(32)
        Case 7&:    BitInByte = TheByte And CByte(64)
        Case 8&:    BitInByte = TheByte And CByte(128)
        End Select
    End Property
    
    Public Property Let BitInByte(ByRef TheByte As Byte, ByVal Pos1to8 As Long, OnOff As Boolean)
        ' Does nothing if Pos1to8 is out of range.
        Select Case Pos1to8
        Case 1&:    If OnOff Then TheByte = TheByte Or CByte(1) Else TheByte = TheByte And Not CByte(1)
        Case 2&:    If OnOff Then TheByte = TheByte Or CByte(2) Else TheByte = TheByte And Not CByte(2)
        Case 3&:    If OnOff Then TheByte = TheByte Or CByte(4) Else TheByte = TheByte And Not CByte(4)
        Case 4&:    If OnOff Then TheByte = TheByte Or CByte(8) Else TheByte = TheByte And Not CByte(8)
        Case 5&:    If OnOff Then TheByte = TheByte Or CByte(16) Else TheByte = TheByte And Not CByte(16)
        Case 6&:    If OnOff Then TheByte = TheByte Or CByte(32) Else TheByte = TheByte And Not CByte(32)
        Case 7&:    If OnOff Then TheByte = TheByte Or CByte(64) Else TheByte = TheByte And Not CByte(64)
        Case 8&:    If OnOff Then TheByte = TheByte Or CByte(128) Else TheByte = TheByte And Not CByte(128)
        End Select
    End Property
    
    
    When dealing with a Byte, it's just easier to test it all out rather than involve any math at all. You can take the same approach with Integers if you'd like, just expand the Select Case statements on out.

    And the only type casting that's being done in this code is the CByte functions, and I believe they're resolved by the compiler (not at runtime) ... and that's only because we don't have a Byte Literal Constant type.

    -------

    In the past few months, I've also posted some code to do something similar with Longs. However, I can't put my finger on it right now. I did use some math in that code, but it was all integer (Long) math. I could have done it as the above is done, but it's supposedly a bit quicker to bit-shift than to do those ANDs and ORs when dealing with Longs. And, you also have to deal with the sign bit when dealing with Longs. I'll try again to find it.

    EDIT: I can't find it. I'm sure I posted it sometime in the last couple of years though. However, the above approach could even be taken with Longs if you wanted and it'd be better than using powers (which require conversion to Double, which isn't good). Just keep extending the Select statement.
    Last edited by Elroy; Mar 11th, 2022 at 10:03 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  17. #17
    Fanatic Member
    Join Date
    Apr 2021
    Posts
    616

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Elroy View Post
    Goodness gracious. That above code is doing implicit type casting all over the place, even to Doubles and back. I don't think that's what you want at all!
    If you meant my code, it doesn't use any other variable types directly WITH the byte array...it just uses a few different variables to handle other aspects of the functions. It's smaller, even smaller than your code, and it (currently) handles up to 32 bits of data per value (the same as a Long would, but using bytes). As I said below my code, I prefer function over form...the code works for what is needed, and it is succinct...I could probably have made it even shorter by removing the do/while and putting in a divisor/remainder calculation (which would also have slightly sped the process up as it doesn't need to loop around. It's essentially about 10 lines of code that performs both the get and set of the bit value, whereas both your code (which only works with up to 8 bytes rather than the required 12 and space for expansion in future up to 32) and the other one above. If you're going to say you will use select case for as many bits as the OP requires, it probably isn't going to be worth posting that...it might be at least semi-fast but I can see a program very quickly becoming bloated with the case options.

    It was just a quick bit of coding and could do with dimming of some of the variables in use within those functions...but it gives the idea for the way in which I would do the job (and actually *does* the job), and would hopefully seed the idea for the OP to write their own based on it.

  18. #18
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Shaggy Hiker View Post
    Does it take less time to access? I don't know how VB6 accesses data, but I don't think there is any advantage to shifting one byte into a register. I'm not even sure it's truly possible, which is probably why a Boolean is taking two bytes when it technically only needs a single bit.
    Testing multiple bits in a bit field is certainly far more performant and far more efficient than using a set of Booleans for the same task. There are examples of this all over the place, the most well known being flags using by many Win32 API functions. CreateWindow's window styles come to mind or the many flags you can set using something like SetWindowLong.

    However, it is not always worth it to use a bit field for boolean data. Lets use a contrived example. Let's say you have a function named IsOverLapping that takes two rectangles and returns a Boolean that tells you whether the two rectangles overlap. You can have it return a Byte which uses only a single bit. In this case however, it's not very efficient. This is because at the machine code level, you're still using an entire 32 bit or 64 bit register yet you are still requiring developers to pluck at it with bitwise operations to obtain the value of the least significant bit. It's more efficient to just use the whole register and a single instruction for testing.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  19. #19

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Arnoutdv View Post
    Code:
    Option Explicit
    
    Private m_Bits(31) As Long
    
    Public Sub InitBits()
      Dim i As Long, lBits As Long
      
      lBits = 1
      For i = 0 To 30
        m_Bits(i) = lValue
        If i < 30 Then lBits = lBits * 2
      Next i
      m_Bits(31) = -2147483648#
    End Sub
    
    Public Sub SetBit(lValue As Long, ByVal lIndex As Long)
    '  Sets indicated bit to one, or ON.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31&
      
      lValue(indx) = lValue(indx) Or m_Bits(ofst)  'turn the bit ON
    End Sub
    
    Public Function GetBit(lValue As Long, ByVal lIndex As Long) As Long
    ' Returns zero if the indicated bit is off, NON-ZERO if on.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31& 'posn MOD 32
      
      GetBit = lValue And m_Bits(ofst)
    End Function
    
    Public Function IsBitSet(lValue As Long, ByVal lIndex As Long) As Boolean
    ' Returns zero if the indicated bit is off, NON-ZERO if on.
      Dim indx As Long, ofst As Long
      
      indx = lIndex \ 32
      ofst = lIndex And 31& 'posn MOD 32
      
      IsBitSet = (lValue And m_Bits(ofst)) <> 0
    End Function
    
    Public Sub ClearBit(lValue As Long, ByVal posn As Long)
    ' Sets indicated bit to zero, or OFF.
      Dim indx As Long, ofst As Long
      
      indx = posn \ 32
      ofst = posn And 31 ' BITS0thru4 ' posn MOD 32
      
      lValue = lValue And (Not m_Bits(ofst)) 'turn the bit OFF
    End Sub
    
    Public Function CountBits(lValue As Long) As Long
      Dim lValue As Long
      
      If lValue Then
        If lValue = -1 Then
          CountBits = CountBits + 32
        Else
          If lValue And &H1 Then CountBits = CountBits + 1
          If lValue And &H2 Then CountBits = CountBits + 1
          If lValue And &H4 Then CountBits = CountBits + 1
          If lValue And &H8 Then CountBits = CountBits + 1
          If lValue And &H10& Then CountBits = CountBits + 1
          If lValue And &H20& Then CountBits = CountBits + 1
          If lValue And &H40& Then CountBits = CountBits + 1
          If lValue And &H80& Then CountBits = CountBits + 1
          If lValue And &H100& Then CountBits = CountBits + 1
          If lValue And &H200& Then CountBits = CountBits + 1
          If lValue And &H400& Then CountBits = CountBits + 1
          If lValue And &H800& Then CountBits = CountBits + 1
          If lValue And &H1000& Then CountBits = CountBits + 1
          If lValue And &H2000& Then CountBits = CountBits + 1
          If lValue And &H4000& Then CountBits = CountBits + 1
          If lValue And &H8000& Then CountBits = CountBits + 1
          If lValue And &H10000 Then CountBits = CountBits + 1
          If lValue And &H20000 Then CountBits = CountBits + 1
          If lValue And &H40000 Then CountBits = CountBits + 1
          If lValue And &H80000 Then CountBits = CountBits + 1
          If lValue And &H100000 Then CountBits = CountBits + 1
          If lValue And &H200000 Then CountBits = CountBits + 1
          If lValue And &H400000 Then CountBits = CountBits + 1
          If lValue And &H800000 Then CountBits = CountBits + 1
          If lValue And &H1000000 Then CountBits = CountBits + 1
          If lValue And &H2000000 Then CountBits = CountBits + 1
          If lValue And &H4000000 Then CountBits = CountBits + 1
          If lValue And &H8000000 Then CountBits = CountBits + 1
          If lValue And &H10000000 Then CountBits = CountBits + 1
          If lValue And &H20000000 Then CountBits = CountBits + 1
          If lValue And &H40000000 Then CountBits = CountBits + 1
          If lValue And &H80000000 Then CountBits = CountBits + 1
        End If
      End If
      
    End Function
    Very valuable code. Your code is very helpful for me to achieve 32 Bit-Options. Thank you, Arnoutdv.

  20. #20

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by SmUX2k View Post
    Very quick bit of code that seems to work for me, and much smaller than the one offered above:
    Code:
    Public BitArray(3, 1000000) As Byte
    
    Public Function getbit(point As Single, loc As Double)
    arrloc = 0: temppoint = point
    Do While temppoint > 8 'Gets the position along the dimensions
        temppoint = temppoint - 8: arrloc = arrloc + 1
        Loop
    getbit = BitArray(arrloc, loc) And 2 ^ (temppoint - 1)
    End Function
    
    Public Function setbit(point As Single, loc As Double, valu As Boolean)
    arrloc = 0: temppoint = point
    Do While temppoint > 8
        temppoint = temppoint - 8: arrloc = arrloc + 1
        Loop
    pos = BitArray(arrloc, loc) And 2 ^ (temppoint - 1)
    If pos = 0 And valu = True Then BitArray(arrloc, loc) = BitArray(arrloc, loc) + 2 ^ (temppoint - 1)
    If pos <> 0 And valu = False Then BitArray(arrloc, loc) = BitArray(arrloc, loc) - 2 ^ (temppoint - 1)
    setbit = getbit(point, loc)
    End Function
    getbit() pulls the value from the array as either zero (false) or non-zero (true)
    setbit() takes a true or false and places it at the designated location

    setbit(8, 100, True) Sets the 8th bit of the 100th value to true

    getbit(8, 100) pulls the value out (as zero or nonzero...shouldn't be difficult to have the output as boolean true or false)

    setbit(8, 100, False) Sets the same bit to false

    It isn't clean code, my code is generally function over form, but it's something that could be worked on from to get what you need...and yeah, took a little longer than 5 minutes but I haven't worked with the bit level in ages :-)
    Very good idea. Your code does take up less memory. Thank you, SmUX2k.

  21. #21

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Quote Originally Posted by Elroy View Post
    Goodness gracious. That above code is doing implicit type casting all over the place, even to Doubles and back. I don't think that's what you want at all!

    If we're dealing with bits in Bytes, here's some code I just hammered out (not even tested, but it should work):

    Code:
    
    Option Explicit
    
    Public Property Get BitInByte(ByRef TheByte As Byte, ByVal Pos1to8 As Long) As Boolean
        ' Returns false if Pos1to8 is out of range.
        Select Case Pos1to8
        Case 1&:    BitInByte = TheByte And CByte(1)
        Case 2&:    BitInByte = TheByte And CByte(2)
        Case 3&:    BitInByte = TheByte And CByte(4)
        Case 4&:    BitInByte = TheByte And CByte(8)
        Case 5&:    BitInByte = TheByte And CByte(16)
        Case 6&:    BitInByte = TheByte And CByte(32)
        Case 7&:    BitInByte = TheByte And CByte(64)
        Case 8&:    BitInByte = TheByte And CByte(128)
        End Select
    End Property
    
    Public Property Let BitInByte(ByRef TheByte As Byte, ByVal Pos1to8 As Long, OnOff As Boolean)
        ' Does nothing if Pos1to8 is out of range.
        Select Case Pos1to8
        Case 1&:    If OnOff Then TheByte = TheByte Or CByte(1) Else TheByte = TheByte And Not CByte(1)
        Case 2&:    If OnOff Then TheByte = TheByte Or CByte(2) Else TheByte = TheByte And Not CByte(2)
        Case 3&:    If OnOff Then TheByte = TheByte Or CByte(4) Else TheByte = TheByte And Not CByte(4)
        Case 4&:    If OnOff Then TheByte = TheByte Or CByte(8) Else TheByte = TheByte And Not CByte(8)
        Case 5&:    If OnOff Then TheByte = TheByte Or CByte(16) Else TheByte = TheByte And Not CByte(16)
        Case 6&:    If OnOff Then TheByte = TheByte Or CByte(32) Else TheByte = TheByte And Not CByte(32)
        Case 7&:    If OnOff Then TheByte = TheByte Or CByte(64) Else TheByte = TheByte And Not CByte(64)
        Case 8&:    If OnOff Then TheByte = TheByte Or CByte(128) Else TheByte = TheByte And Not CByte(128)
        End Select
    End Property
    
    
    When dealing with a Byte, it's just easier to test it all out rather than involve any math at all. You can take the same approach with Integers if you'd like, just expand the Select Case statements on out.

    And the only type casting that's being done in this code is the CByte functions, and I believe they're resolved by the compiler (not at runtime) ... and that's only because we don't have a Byte Literal Constant type.

    -------

    In the past few months, I've also posted some code to do something similar with Longs. However, I can't put my finger on it right now. I did use some math in that code, but it was all integer (Long) math. I could have done it as the above is done, but it's supposedly a bit quicker to bit-shift than to do those ANDs and ORs when dealing with Longs. And, you also have to deal with the sign bit when dealing with Longs. I'll try again to find it.

    EDIT: I can't find it. I'm sure I posted it sometime in the last couple of years though. However, the above approach could even be taken with Longs if you wanted and it'd be better than using powers (which require conversion to Double, which isn't good). Just keep extending the Select statement.
    Very nice code, it's easy to extend to Integer and Long. Select-Case is indeed simple and effective. Thank you, Elroy.

  22. #22

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Boolean or Byte or Bit ?

    Sorry for the late reply. Thank you to everyone involved in this thread.

    Arnoutdv, SmUX2k and Elroy offer three different types of codes, each with its own unique value. I combined the advantages of the above three pieces of code and put together a piece of code that fully meets my needs:
    Code:
    Public Function GetBit(ByRef nBitOptions As Integer, ByVal nBitIndex As Long) As Boolean
        '--- Returns false if nBitIndex (1 to 16) is out of range.
        Select Case nBitIndex
        Case 1&:    GetBit = nBitOptions And &H1
        Case 2&:    GetBit = nBitOptions And &H2
        Case 3&:    GetBit = nBitOptions And &H4
        Case 4&:    GetBit = nBitOptions And &H8
        Case 5&:    GetBit = nBitOptions And &H10
        Case 6&:    GetBit = nBitOptions And &H20
        Case 7&:    GetBit = nBitOptions And &H40
        Case 8&:    GetBit = nBitOptions And &H80
        Case 9&:    GetBit = nBitOptions And &H100
        Case 10&:  GetBit = nBitOptions And &H200
        Case 11&:  GetBit = nBitOptions And &H400
        Case 12&:  GetBit = nBitOptions And &H800
        Case 13&:  GetBit = nBitOptions And &H1000
        Case 14&:  GetBit = nBitOptions And &H2000
        End Select
        
    End Function
    
    Public Sub SetBit(ByRef nBitOptions As Integer, ByVal nBitIndex As Long, newValue As Boolean)
        '--- Does nothing if nBitIndex (1 to 16) is out of range.
        Select Case nBitIndex
        Case 1&:    If newValue Then nBitOptions = nBitOptions Or &H1 Else nBitOptions = nBitOptions And Not &H1
        Case 2&:    If newValue Then nBitOptions = nBitOptions Or &H2 Else nBitOptions = nBitOptions And Not &H2
        Case 3&:    If newValue Then nBitOptions = nBitOptions Or &H4 Else nBitOptions = nBitOptions And Not &H4
        Case 4&:    If newValue Then nBitOptions = nBitOptions Or &H8 Else nBitOptions = nBitOptions And Not &H8
        Case 5&:    If newValue Then nBitOptions = nBitOptions Or &H10 Else nBitOptions = nBitOptions And Not &H10
        Case 6&:    If newValue Then nBitOptions = nBitOptions Or &H20 Else nBitOptions = nBitOptions And Not &H20
        Case 7&:    If newValue Then nBitOptions = nBitOptions Or &H40 Else nBitOptions = nBitOptions And Not &H40
        Case 8&:    If newValue Then nBitOptions = nBitOptions Or &H80 Else nBitOptions = nBitOptions And Not &H80
        Case 9&:    If newValue Then nBitOptions = nBitOptions Or &H100 Else nBitOptions = nBitOptions And Not &H100
        Case 10&:  If newValue Then nBitOptions = nBitOptions Or &H200 Else nBitOptions = nBitOptions And Not &H200
        Case 11&:  If newValue Then nBitOptions = nBitOptions Or &H400 Else nBitOptions = nBitOptions And Not &H400
        Case 12&:  If newValue Then nBitOptions = nBitOptions Or &H800 Else nBitOptions = nBitOptions And Not &H800
        Case 13&:  If newValue Then nBitOptions = nBitOptions Or &H1000 Else nBitOptions = nBitOptions And Not &H1000
        Case 14&:  If newValue Then nBitOptions = nBitOptions Or &H2000 Else nBitOptions = nBitOptions And Not &H2000
        End Select
     
    End Sub
    It feels very good to learn different knowledge points from different people, and then sum up a solution that is completely suitable for the actual project needs.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width