Blade
Blade

Reputation: 21

Decoding exponential formula in VB

I am working on a program that allows the user to set an automatic task to run at certain times.

Here is an example of what the day of week selection looks like:

enter image description here

Each day is assigned a value of 2 ^ (x - 1), with x being the day number (Sun=1, Mon=2, Tue=3, etc..)

Then, the code goes through and calculates the sum of all the checked boxes to get a single numeric value that is stored in the database.

For example, if all the boxes are checked, the final value would be 1+2+4+8+16+32+64 = 127.

Here's what the VB code looks like:

If mycheckbox.Checked = True Then
    dowVal = dowVal + 2 ^ (x - 1)
End If

This repeats for every checkbox, substituting x for the day number and mycheckbox for each day's unique checkbox id. Once it runs though all 7 days, dowVal is the final value that gets sent to the database.

Generating the dowVal based on the checkboxes is easy enough, but how would I go about reversing this process?

Given a single dowVal, I need to go and programmatically check all the corresponding boxes and produce the exact same combination of checked boxes that were used to generate dowVal in the first place.

I initially tried using the inverse of the IF statement above like so:

 If dowVal = 2 ^ (x - 1) Then
            mycheckbox.Checked = True
 End If

Obviously this only works if a single checkbox is checked because it doesn't account for the summed values.

The only way I can think to do it would be a massive set of IF statements that account for all possible permutations, but this wouldn't work for other portions of the program that use this same formula such as minute of day, because that has 60 checkboxes and the number of combinations would be exponentially insane.

How would I go about decoding dowVal and translating that back into checked boxes that does not involve an exponential amount of cases?

Upvotes: 0

Views: 155

Answers (2)

Bradley Uffner
Bradley Uffner

Reputation: 16991

This looks like it is ideal for a "Flags Enum". You create an enumeration for each day of the week with values of powers of 2. Then cast the encoded data in to a variable of the Enumeration type. Now you can just do this:

dim days as DaysOfWeek = ctype(value,DaysOfWeek)
if days.HasFlag(DaysOfWeek.Monday) then ...

More information can be found on MSDN.

Upvotes: 0

Nefariis
Nefariis

Reputation: 3549

I wont give you the full answer becuase I am assuming this is for homework but I will give you a hint.

Start backwards.

If your number is 77

Start with 64. 64 fits into 77, which means you are left with 13 - then keep going backwards until you are left with the correct days (64,8,4,1).

Good Luck

Dim num = 77

for x as integer = {64,32,16,8,4,2,1,}
    if num - x >= 0 then
         select case num
              case 64 : checkbox64.checked = true
              case 32 : checkbox32.checked = true
              'blah blah 
         end select
         num -= x
    end if
next

Upvotes: 2

Related Questions