|
-
May 20th, 2025, 06:34 AM
#1
Thread Starter
PowerPoster
I have never understood bit operations.
I have this line of code:
Code:
If (ShuffleTypeID <> idx_ShuffleType_EquipBest) And (ShuffleTypeID <> idx_ShuffleType_EquipWorst) Then Exit Function
I'd like it to be this:
Code:
If ShuffleTypeID <> (idx_ShuffleType_EquipBest Or idx_ShuffleType_EquipWorst) Then Exit Function
To see what that does I did this:
Code:
Sub SomeSub
Dim x As Integer
x = 2
MsgBox x = 5 or 7 ' Returns 7 instead of False.
I don't understand that.
-
May 20th, 2025, 06:45 AM
#2
Thread Starter
PowerPoster
Re: I have never understood bit operations.
I didn't put the 5 or 7 in Parens.
Code:
Sub SomeSub
Dim x As Integer
x = 2
MsgBox x = (5 Or 7) ' Returns False.
MsgBox x = (2 or 7) ' Returns False.
It still returned False.
-
May 20th, 2025, 07:03 AM
#3
Re: I have never understood bit operations.
Do you really want bit operations or do you try to shortcut some boolean logic?
Code:
0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
5 = 0101
6 = 0110
7 = 0111
An OR on bitvalues will fill all positions with 1 if there is a 1 on the position in one of the values
5 or 7:
5 = 0101
7 = 0111
----------
x = 0111 -> value 7
2 or 7:
2 = 0010
7 = 0111
----------
x = 0111 -> value 7
Your code:
x = 2
n = 5 Or 7 ' -> 7
MsgBox x = n -> False
x = 2
n = 2 Or 7 ' -> 7
MsgBox x = n -> False
-
May 20th, 2025, 07:07 AM
#4
Thread Starter
PowerPoster
Re: I have never understood bit operations.
I don't know the difference. But yes, I'm just trying to make it shorter and clearer.
Essentially my goal with all my code is to make it so obvious what it's doing that comments are optional (I know I should add them anyway).
But basically I would rather read through the code and know what it's doing instead of reading comments.
-
May 20th, 2025, 07:09 AM
#5
Thread Starter
PowerPoster
Re: I have never understood bit operations.
Would XOR work? I'll try that and see what it does.
Result: Nope.
-
May 20th, 2025, 07:58 AM
#6
Re: I have never understood bit operations.
What do want to achieve?
A shortcut to "(x = 2) or (x = 7)"?
-
May 20th, 2025, 08:11 AM
#7
Thread Starter
PowerPoster
Re: I have never understood bit operations.
Yes.
If (x <> 2) And (x <> 7) Then Exit Function. ' One Case must be True to continue (x = 2) or (x = 7) continues.
-
May 20th, 2025, 08:19 AM
#8
Thread Starter
PowerPoster
Re: I have never understood bit operations.
I'm just trying to shorten one line of code because I write this same line of code a lot.
And I think it's much faster to read if it's what I'm trying to do.
This is the sub in question not that it matter. It's just one line of code near the top:
Code:
Private Function EquipBestWorstItems(ByRef PlayerItems As cItems, ByRef ShuffleTypeID As SHUFFLE_TYPE_INDEX) As Long
Dim m_item As cItem
Dim m_EquippedItem As cItem
Dim nResult As Long
If Not ValidObject(PlayerItems) Then Exit Function
If PlayerItems.Count = 0 Then Exit Function
' The next line is the one I want to short-ciruit:
If (ShuffleTypeID <> idx_ShuffleType_EquipBest) And (ShuffleTypeID <> idx_ShuffleType_EquipWorst) Then Exit Function
For Each m_item In PlayerItems
Set m_EquippedItem = EquippedItem(m_item.ItemSlotID)
If ValidObject(m_EquippedItem) Then ' Item Slot Is Equipped. Check if m_Item is Better or Worse.
Select Case ShuffleTypeID
Case idx_ShuffleType_EquipBest ' Equip if Better.
If m_item.LevelRequirement > m_EquippedItem.LevelRequirement Then
nResult = EquipItem(m_item, PlayerItems, idx_AcquisitionMethod_Distribute)
End If
Case idx_ShuffleType_EquipWorst ' Equip if Worse.
If m_item.LevelRequirement < m_EquippedItem.LevelRequirement Then
nResult = EquipItem(m_item, PlayerItems, idx_AcquisitionMethod_Distribute)
End If
End Select
Else ' Item Slot is Not Equipped. Any Item is better.
nResult = EquipItem(m_item, PlayerItems, idx_AcquisitionMethod_Distribute)
End If
If nResult <> 1 Then TransferItem m_item, PlayerItems, BackpackItems, idx_AcquisitionMethod_Distribute ' Equip failed. Store Item in Backpack.
Next m_item
EquipBestWorstItems = 1
End Function
-
May 20th, 2025, 08:30 AM
#9
Re: I have never understood bit operations.
 Originally Posted by cafeenman
Yes.
If (x <> 2) And (x <> 7) Then Exit Function. ' One Case must be True to continue (x = 2) or (x = 7) continues.
Why not use Select Case?
Code:
Select Case ShuffleTypeID
Case idx_ShuffleType_EquipBest, _
idx_ShuffleType_EquipWorst
' Do Something
End Select
-
May 20th, 2025, 08:32 AM
#10
Re: I have never understood bit operations.
 Originally Posted by cafeenman
I'm just trying to shorten one line of code because I write this same line of code a lot.
Or how about a function?
Code:
Function IsBestOrWorstShuffleType(ByVal ShuffleTypeId As eShuffleTypeId) As Boolean
IsBestOrWorstShuffleType = (ShuffleTypeId = idx_ShuffleType_EquipBest) Or _
(ShuffleTypeId = idx_ShuffleType_EquipWorst)
End Function
-
May 20th, 2025, 08:34 AM
#11
Re: I have never understood bit operations.
One of the advantages of a function is that if your logic needs to change down the road, you only need to modify the code in one place (and perhaps do a global find/replace on the old function name).
-
May 20th, 2025, 08:36 AM
#12
Thread Starter
PowerPoster
Re: I have never understood bit operations.
That would work.
More Generically I'd probably name it:
Function OneOfTheseIsTrue(ByRef ValueSought, ByRef Value1, ByRef Value2) as Boolean
-
May 20th, 2025, 08:38 AM
#13
Thread Starter
PowerPoster
Re: I have never understood bit operations.
Actually, make thelast arguments a paramarray and loop through it until one is true.
-
May 20th, 2025, 08:39 AM
#14
Thread Starter
PowerPoster
Re: I have never understood bit operations.
CafeenMan luvs functions. Just didn't think about it in this circumstance.
Thanks.
-
May 20th, 2025, 08:41 AM
#15
Thread Starter
PowerPoster
Re: I have never understood bit operations.
LOL... actually....
Function NoneOfTheseAreTrue is even better I think.
That way instead of always using Not to get out, just get out.
E.g.
If Not OneOfTheseIsTrue(...) Then Exit Function
or
If NoneOfTheseAreTrue(...) Then Exit Function
-
May 20th, 2025, 08:43 AM
#16
Re: I have never understood bit operations.
 Originally Posted by cafeenman
CafeenMan luvs functions. Just didn't think about it in this circumstance.
Thanks. 
Just don't use any procedure with a ParamArray in a performance critical inner loop and the game won't lag too much :-))
I personally would always use plain If statement with a single Or operator not only for performance but for readability too.
cheers,
</wqw>
-
May 20th, 2025, 08:47 AM
#17
Thread Starter
PowerPoster
Re: I have never understood bit operations.
Haven't tested it yet but this is my first shot at it:
Code:
Public Function NoneAreTrue(ByRef ValueSought, ParamArray Values()) As Boolean
Dim n As Long
For n = LBound(Values) To UBound(Values)
If Values(n) = ValueSought Then Exit Function
Next n
NoneAreTrue = True
End Function
Code:
' Old
If (ShuffleTypeID <> idx_ShuffleType_EquipBest) And (ShuffleTypeID <> idx_ShuffleType_EquipWorst) Then Exit Function
' New. Not much shorter and not sure it's easier to follow.
If NoneAreTrue(ShuffleTypeID, idx_ShuffleType_EquipBest, idx_ShuffleType_EquipWorst) Then Exit Function
Last edited by cafeenman; May 20th, 2025 at 08:58 AM.
-
May 20th, 2025, 09:13 AM
#18
Re: I have never understood bit operations.
VB6 doesn't have separate sets of boolean versus bitwise operators, like other C-like languages do. For instance, in C, we've got & (bitwise) versus && (boolean), or | (bitwise) versus || (boolean). And there are others as well.
In VB6, we've just got "And" and "Or" (and the others). And they're all bitwise, not boolean. Now, we do have a boolean variable type, which is just a special case of an Integer (two byte) variable, where it attempts to have a value of either &h0000 (0) or &hFFFF (-1).
But, because "And" and "Or" are bitwise (and not boolean), things can get confusing. If you just want a True or False answer, and you're dealing with variables that aren't initially Boolean variables, the easiest thing to do is just cast them to Boolean with the CBool() function before you start. That way, everything will be done as a boolean operation.
To explain a bit, if we're starting with either a &h0000 or &hFFFF, at that point there's no distinction between a bitwise operation and a boolean operation, so our "And" and "Or" will work like boolean operators, solving any problems.
If you just want a trivial example of how things can get confusing, here are two different evaluations:
Code:
Dim i As Integer, j As Integer
Dim b As Boolean
i = 1
j = 2
b = i And j ' In this case, b will be False.
b = CBool(i) And CBool(j) ' In this case, b will be True.
Try it if you don't believe me.
I won't go into all the nitty-gritty of how bitwise actually works, but again, if it's starting with Boolean variables, the "And" and "Or" will effectively work like Boolean operators. But, if we're starting with something that's not Boolean, that's when the outcome can start getting tricky, as in the "b = i And j" line above.
Just to add a final comment, once you understand bitwise (under the hood), it does all make sense. But, if we're just after boolean answers, it's often not necessary to get into all the details of bitwise.
Last edited by Elroy; May 20th, 2025 at 09:18 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.
-
May 20th, 2025, 09:26 AM
#19
Thread Starter
PowerPoster
Re: I have never understood bit operations.
 Originally Posted by jpbro
Why not use Select Case?
Code:
Select Case ShuffleTypeID
Case idx_ShuffleType_EquipBest, _
idx_ShuffleType_EquipWorst
' Do Something
End Select
Because that's going in the opposite direction - longer code.
-
May 20th, 2025, 09:30 AM
#20
Re: I have never understood bit operations.
 Originally Posted by cafeenman
Yes.
If (x <> 2) And (x <> 7) Then Exit Function. ' One Case must be True to continue (x = 2) or (x = 7) continues.
Code:
Private Sub Command1_Click()
Dim x As Long
x = 2
Debug.Print ValueIn(x, 5, 7)
Debug.Print ValueIn(x, 1, 3, 4, 5, 7)
Debug.Print ValueIn(x, 2, 7)
End Sub
Private Function ValueIn(ByVal Value As Long, ParamArray Values()) As Boolean
Dim i As Long
For i = LBound(Values) To UBound(Values)
If Values(i) = Value Then
ValueIn = True
Exit For
End If
Next i
End Function
-
May 20th, 2025, 09:40 AM
#21
Thread Starter
PowerPoster
Re: I have never understood bit operations.
See #17.
-
May 20th, 2025, 10:36 AM
#22
Re: I have never understood bit operations.
 Originally Posted by cafeenman
See #17. 
Ah, sorry missed it
-
May 20th, 2025, 12:56 PM
#23
Re: I have never understood bit operations.
 Originally Posted by cafeenman
I have this line of code:
Code:
If (ShuffleTypeID <> idx_ShuffleType_EquipBest) And (ShuffleTypeID <> idx_ShuffleType_EquipWorst) Then Exit Function
I'd like it to be this:
Code:
If ShuffleTypeID <> (idx_ShuffleType_EquipBest Or idx_ShuffleType_EquipWorst) Then Exit Function
If you want to use a bit field, you can use the AND operator to perform a single test:-
Code:
Private Sub Form_Load()
Dim idx_ShuffleType_EquipBest As Long
Dim idx_ShuffleType_EquipWorst As Long
Dim flag1 As Long
Dim flag2 As Long
Dim BestAndWorst As Long
Dim ShuffleTypeID1 As Long
Dim ShuffleTypeID2 As Long
Dim ShuffleTypeID3 As Long
Dim ShuffleTypeID4 As Long
idx_ShuffleType_EquipBest = 1
idx_ShuffleType_EquipWorst = 2
'This variable has the best and worst flags set
BestAndWorst = idx_ShuffleType_EquipBest Or idx_ShuffleType_EquipWorst
'Extra flags to make things interesting
flag1 = 4
flag2 = 8
flag3 = 16
ShuffleTypeID1 = idx_ShuffleType_EquipBest
ShuffleTypeID2 = idx_ShuffleType_EquipWorst
ShuffleTypeID3 = flag1 Or flag2 Or flag3 Or idx_ShuffleType_EquipBest
'This is the only one that isn't best or worst so
'it should invoke an exit
ShuffleTypeID4 = flag3 Or flag2
'Only one the last one should print "Exit Function" as it's the only that is neither best or worst
'****************************************************************************************************
If Not CBool(ShuffleTypeID1 And BestAndWorst) Then Debug.Print "Exit Function" Else Debug.Print "Don't Exit Function"
If Not CBool(ShuffleTypeID2 And BestAndWorst) Then Debug.Print "Exit Function" Else Debug.Print "Don't Exit Function"
If Not CBool(ShuffleTypeID3 And BestAndWorst) Then Debug.Print "Exit Function" Else Debug.Print "Don't Exit Function"
If Not CBool(ShuffleTypeID4 And BestAndWorst) Then Debug.Print "Exit Function" Else Debug.Print "Don't Exit Function"
End Sub
The bread and butter is this line:-
Code:
If Not CBool(ShuffleTypeID1 And BestAndWorst) Then Debug.Print "Exit Function" Else Debug.Print "Don't Exit Function"
Which in your code would be:-
Code:
If Not CBool(ShuffleTypeID And BestAndWorst) Then Exit Function
The idea here is that if either the best or worst bits are set then ANDing with with a bit field where both these bits are set will always return non-zero.
-
May 20th, 2025, 02:10 PM
#24
Thread Starter
PowerPoster
Re: I have never understood bit operations.
So if I wanted to reduce that to one line of code then it would be thus?
Code:
If Not CBool(ShuffleTypeID And (idx_ShuffleType_EquipBest Or idx_ShuffleType_EquipWorst)) Then Exit Function
-
May 20th, 2025, 03:08 PM
#25
Re: I have never understood bit operations.
 Originally Posted by cafeenman
So if I wanted to reduce that to one line of code then it would be thus?
Code:
If Not CBool(ShuffleTypeID And (idx_ShuffleType_EquipBest Or idx_ShuffleType_EquipWorst)) Then Exit Function
Yes. However, there is a very important caveat, you must be operating on bit fields. What this means is that the values you're dealing cannot be arbitrary. Each state must correspond to a single bit. You can see that in the code I posted:-
Code:
idx_ShuffleType_EquipBest = 1
idx_ShuffleType_EquipWorst = 2
flag1 = 4
flag2 = 8
flag3 = 16
Notice that they increment in powers of 2. This is what allows them to be combined into a single bit field by the OR operator.
Last edited by Niya; May 20th, 2025 at 03:12 PM.
-
May 20th, 2025, 03:25 PM
#26
Thread Starter
PowerPoster
Re: I have never understood bit operations.
I'm going to pass on this method although I can see it has a lot of value for other things.
But it would require translation and conversion because everything in the program is die-rolls that return 1 through number of die sides.
nDieRoll = RollDie(d6)
ShuffleType = 2 ^ (nDieRoll - 1) '
Just to check my math.
rolls
1: (2 ^ (1 - 1) = 1
2: (2 ^ (2 - 1) = 2
3: (2 ^ (3 - 1) = 4
4: (2 ^ (4 - 1) = 8
5: etc..
6:
Actually it's not so bad since this is done in only one Function. All functions called by this function are sent the enum value, not the die roll.
Last edited by cafeenman; May 20th, 2025 at 03:47 PM.
-
May 20th, 2025, 03:30 PM
#27
Thread Starter
PowerPoster
Re: I have never understood bit operations.
Code:
Public Enum SHUFFLE_TYPE_INDEX
idx_ShuffleType_EquipRandom = 1 ' 1 Equip Random Items.
idx_ShuffleType_EquipBest ' 2 Prioritize Highest Level Items.
idx_ShuffleType_EquipWorst ' 3 Prioritize Lowest Level Item.
idx_ShuffleType_BackpackPriority ' 4 Prioritize Backpack Items.
idx_ShuffleType_EquippedPriority ' 5 Prioritize Equipped Items.
idx_ShuffleType_UnequipAll ' 6 Store All Items (go naked).
End Enum
Public Const MIN_SHUFFLE_TYPE_INDEX As Long = idx_ShuffleType_EquipRandom
Public Const MAX_SHUFFLE_TYPE_INDEX As Long = idx_ShuffleType_UnequipAll
Sub SomeSub
dim nShuffleType as SHUFFLE_TYPE_INDEX
nShuffleType = RollDie(MAX_SHUFFLE_TYPE_INDEX )
End Sub
-
May 20th, 2025, 09:57 PM
#28
Re: I have never understood bit operations.
 Originally Posted by cafeenman
Code:
Public Enum SHUFFLE_TYPE_INDEX
idx_ShuffleType_EquipRandom = 1 ' 1 Equip Random Items.
idx_ShuffleType_EquipBest ' 2 Prioritize Highest Level Items.
idx_ShuffleType_EquipWorst ' 3 Prioritize Lowest Level Item.
idx_ShuffleType_BackpackPriority ' 4 Prioritize Backpack Items.
idx_ShuffleType_EquippedPriority ' 5 Prioritize Equipped Items.
idx_ShuffleType_UnequipAll ' 6 Store All Items (go naked).
End Enum
Public Const MIN_SHUFFLE_TYPE_INDEX As Long = idx_ShuffleType_EquipRandom
Public Const MAX_SHUFFLE_TYPE_INDEX As Long = idx_ShuffleType_UnequipAll
Sub SomeSub
dim nShuffleType as SHUFFLE_TYPE_INDEX
nShuffleType = RollDie(MAX_SHUFFLE_TYPE_INDEX )
End Sub
Oh I understand now. ShuffleType is not actually a bit field. You just want to simplify the comparisons. Well you can do this using primes if you wanted to:-
Code:
Public Enum SHUFFLE_TYPE_INDEX
idx_ShuffleType_EquipRandom = 2 ' 1 Equip Random Items.
idx_ShuffleType_EquipBest = 3 ' 2 Prioritize Highest Level Items.
idx_ShuffleType_EquipWorst = 5 ' 3 Prioritize Lowest Level Item.
idx_ShuffleType_BackpackPriority = 7 ' 4 Prioritize Backpack Items.
idx_ShuffleType_EquippedPriority = 11 ' 5 Prioritize Equipped Items.
idx_ShuffleType_UnequipAll = 13 ' 6 Store All Items (go naked).
End Enum
Private Sub Form_Load()
Dim st(0 To 5) As SHUFFLE_TYPE_INDEX
st(0) = idx_ShuffleType_EquipRandom
st(1) = idx_ShuffleType_EquipBest
st(2) = idx_ShuffleType_EquipWorst
st(3) = idx_ShuffleType_BackpackPriority
st(4) = idx_ShuffleType_EquippedPriority
st(5) = idx_ShuffleType_UnequipAll
For i = LBound(st) To UBound(st)
'Filter out all options that are not the best and not the worst
If (idx_ShuffleType_EquipBest * idx_ShuffleType_EquipWorst) Mod st(i) Then Debug.Print st(i) & " : " & "Exit Function"
Next
End Sub
The only caveat here is that you must use prime numbers for the enum values in order for this to work.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|