score combinations

majhl

Registered User.
Local time
Today, 09:10
Joined
Mar 4, 2008
Messages
89
On a paper form, people are presented with 7 options, 1, 2, 4, 8, 16, 32, 64 (it doesn't what these numbers correspond to). They can select any or all of these options.

However, what is recorded in the database is a single number. If the person selected 1 and 4 and 16, the number is (1+4+16=) 21. There is no other way to achieve a score of 21 - it will always be 1+4+16. This is the same for any of the score combinations (I think!). The problem I'm now faced with is to return these scores to their constituent combinations. I could do this the long way, i.e. write down all the possible combinations and proceed from there. (We can ignore the base numbers themselves).

I'm hoping though that there is an easier way to do this. For example, 2 = 2 to the power of 1, 4 = 2 to the power of 2, 8 = 2 to the power of 4 etc etc. Can I use this in some way to achieve what I want?

Thanks for any help.
 
Use the Or and And operator to perform bitwise operations.

For example, to add 4 to the result:

Code:
MyNumber = MyNumber Or 4

Then to check if there is a 4 in it:

Code:
If MyNumber And 4 Then

Of course, this works only for powers of 2.
 
Yes, it is easy to get the data back out of a structure like this using the boolean "AND" operator. As you suspected, it is a base 2 (binary) representation of your data. In brief, 1 AND 3 = True, 2 AND 3 = True, 2 AND 4 = False, 4 AND 21 = True, 8 AND 21 = False, and so forth.

You haven't really given us enough specific information about the implementation and what you expect out to give you a sample, though.

You'll find this exact type of implementation in many programming paradigms including the "constants" that define how a "MsgBox" behaves. It is unlikely that this is the best way to solve the problem your system is trying to solve but it does work.
 
Thanks to both of you for your replies, which got me thinking. Sorry if I didn't explain myself very well. Anyway, I came up with a solution which I think works well.

<Edit> I created 7 new variables in the relevant table called ap1, ap2, ab4, ap8...ap64.</edit>

Suppose the first value in my recordset is '57'. The second if statement ('If intpain >= 32') establishes this and updates the variable 'ap32' to 1. The same statement then subtracts 32 from 57, leaving 25.

The next if statement (If intpain >= 16) catches the fact that intpain is >=16 and updates the variable 'ap16' to 1, and so on. By the end of the code, we establish that 57 is composed of 32, 16, 8 and 1.

Here it is:

Code:
Do Until rst.EOF = True

intpain = rst!when_pain

'64
If intpain >= 64 Then
    
    rst.Edit
    rst!ap64 = 1
    rst.Update

intpain = intpain - 64

End If

'32
If intpain >= 32 Then
    
    rst.Edit
    rst!ap32 = 1
    rst.Update
    
intpain = intpain - 32

End If

'16
If intpain >= 16 Then
    
    rst.Edit
    rst!ap16 = 1
    rst.Update
    
intpain = intpain - 16

End If

'8
If intpain >= 8 Then
    
    rst.Edit
    rst!ap8 = 1
    rst.Update
    
intpain = intpain - 8
   
End If

'4
If intpain >= 4 Then
    
    rst.Edit
    rst!ap4 = 1
    rst.Update

intpain = intpain - 4

End If

'2
If intpain >= 2 Then
    
    rst.Edit
    rst!ap2 = 1
    rst.Update

intpain = intpain - 2

End If

'1
If intpain >= 1 Then
    
    rst.Edit
    rst!ap1 = 1
    rst.Update

intpain = intpain - 1

End If

rst.MoveNext

Loop
 
Last edited:
But suppose you wanted 65?

With that code, you'd get 64+32+16+8+4+2+1=127 when it's just 64 + 1 = 65.
 
what you have done, is actually emulated the way bitwise operations work.

eg a value of 57 is held as

1
26310000
84268421

00111001

ie a 1 in positions 32,16,8,1 = 32+16+8+1 = 57

you can test these by "and"ing the number with an appropriate mask

so if you want to test for the 32 bit

then 57 and 32 = 32

the 57 bitmask is
00111001

the 32 bitmask is
00100000

anding thesev two returns a 1 iff (if and only if) both values are 1

hence

00111001 logical and
00100000 =
00100000

hence this proves the 32 bit is set.

-you have done the same thing effectively with your code operations.

-----------
note that logical xor operation is extremely useful as it toggles values -
ie a xor b = c
c xor b = a again

which makes xor very useful in simple encryption algorithms
 
But suppose you wanted 65?

With that code, you'd get 64+32+16+8+4+2+1=127 when it's just 64 + 1 = 65.

Would I?

Code:
'lets suppose intpain = 65

If intpain >= 64 Then
    
    rst.Edit
    rst!ap64 = 1
    rst.Update

intpain = intpain - 64
'so intpain = 65 - 64

so the next bit of code to fire is:

Code:
If intpain >= 1 Then
    
    rst.Edit
    rst!ap1 = 1
    rst.Update

intpain = intpain - 1

I've checked a few instances where the value is 65 and the result after I run the code is a combination of 64 and 1.
 
Aha, I did miss that line. My apologies.

As for the table structure, why not just store the variable instead of 8 columns? You always can discover whether it has one of column by AND'ing it.
 
what you have done, is actually emulated the way bitwise operations work.

eg a value of 57 is held as

1
26310000
84268421

00111001

ie a 1 in positions 32,16,8,1 = 32+16+8+1 = 57

you can test these by "and"ing the number with an appropriate mask

so if you want to test for the 32 bit

then 57 and 32 = 32

the 57 bitmask is
00111001

the 32 bitmask is
00100000

anding thesev two returns a 1 iff (if and only if) both values are 1

hence

00111001 logical and
00100000 =
00100000

hence this proves the 32 bit is set.

-you have done the same thing effectively with your code operations.

Thanks very much for the reply.
 
i dont think you need complex code for this

if you have 8 check boxes

then the check boxes repesent placements
128
64
32
16
8
4
2
1

and a value mynum representing the combined flags

then simply
tickbox128 = mynum and 128
tickbox64 = mynum and 64
tickbox32 = mynum and 32

and to reset the mynum (there may be an easier way, but simply)

mynum=0
if tickbox128 then mynum = mynum+128
if tickbox64 then mynum = mynum+64
if tickbox32 then mynum = mynum+32

etc
 
Aha, I did miss that line. My apologies.

As for the table structure, why not just store the variable instead of 8 columns? You always can discover whether it has one of column by AND'ing it.


Yes, I know the old 'if it can be derived, don't store it' rule. The data is going to a user who's going to be doing some analysis of the breakdown.
 
But suppose you wanted 65?

With that code, you'd get 64+32+16+8+4+2+1=127 when it's just 64 + 1 = 65.

Because you subtract 64 from intpain after testing if intpain >= 64 the code works correctly.
 

Users who are viewing this thread

Back
Top Bottom