HI there, I'm slightly new to programming, more of a hobby. I am wondering if a the following logic or technique has a specific name, or term. My current project has 7 check boxes, one for each day of the week. I needed an easy to save which boxes were checked.
The following is the method to saved the checked boxes to a single number. Each checkbox gets a value that is double from the last check box. When I want to find out which boxes are checked, I work backwards, and see how many times I can divide the total value by the checkbox value.
private int SetSelectedDays()
{
int selectedDays = 0;
selectedDays += (dayMon.Checked) ? 1 : 0;
selectedDays += (dayTue.Checked) ? 2 : 0;
selectedDays += (dayWed.Checked) ? 4 : 0;
selectedDays += (dayThu.Checked) ? 8 : 0;
selectedDays += (dayFri.Checked) ? 16 : 0;
selectedDays += (daySat.Checked) ? 32 : 0;
selectedDays += (daySun.Checked) ? 64 : 0;
return selectedDays;
}
private void SelectedDays(int n)
{
if ((n / 64 >= 1) & !(n / 64 >= 2))
{
n -= 64;
daySun.Checked = true;
}
if ((n / 32 >= 1) & !(n / 32 >= 2))
{
n -= 32;
daySat.Checked = true;
}
if ((n / 16 >= 1) & !(n / 16 >= 2))
{
n -= 16;
dayFri.Checked = true;
}
if ((n / 8 >= 1) & !(n / 8 >= 2))
{
n -= 8;
dayThu.Checked = true;
}
if ((n / 4 >= 1) & !(n / 4 >= 2))
{
n -= 4;开发者_如何转开发
dayWed.Checked = true;
}
if ((n / 2 >= 1) & !(n / 2 >= 2))
{
n -= 2;
dayTue.Checked = true;
}
if ((n / 1 >= 1) & !(n / 1 >= 2))
{
n -= 1;
dayMon.Checked = true;
}
if (n > 0)
{
//log event
}
}
The method works well for what I need it for, however, if you do see another way of doing this, or a better way to writing, I would be interested in your suggestions.
Someone else mentioned bit masking, but I thought I would show you a way to simplify your code.
daySun.Checked = (n & 64) == 64;
daySat.Checked = (n & 32) == 32;
dayFri.Checked = (n & 16) == 16;
dayThu.Checked = (n & 8) == 8;
dayWed.Checked = (n & 4) == 4;
dayTue.Checked = (n & 2) == 2;
dayMon.Checked = (n & 1) == 1;
This resembles bitmasking. When I can find the blog I read this week using this exact example I'll post it!
Ah got it! Here it is.
You can then do things like:
DaysOfWeek week = DaysOfWeek.Sunday | DaysOfWeek.Monday;
to select Sunday and Monday. Or in your example, when you check the value of each checkbox you can do:
DaysOfWeek week = DaysOfWeek.None; // DaysOfWeek.None = 0
if (Monday.Checked)
{
week |= DaysOfWeek.Monday;
}
and to check if a particular day is set:
DaysOfWeek week = DaysOfWeek.Monday | DaysOfWeek.Tuesday;
// this will be FALSE (so Wednesday will remain unchecked) because "week" contains Monday/Tuesday, but not Wednesday.
if ((week & DaysOfWeek.Wednesday) == DaysOfWeek.Wednesday)
{
Wednesday.Checked = true;
}
EDIT:
.NET's built-in DayOfWeek does not allow for bitmasking multiple values, so you'll need to roll your own DaysOfWeek
enum.
You could create an enum with all days and mark it with the attribute [Flags] then give each day the same value as your (bla.checked) ? XX..
then you could use +=, and, or to get the same functionality..
so to check if a value contains lets say monday you would do
if (myEnum & Days.Monday == Days.Monday) { ... }
It is called bitmasking and you can do the same thing more easily using an Enum with the Flags attribute.
It's called a bitfield, and yes, it's the most space-efficient way to solve this. Using separate booleans will probably use more memory, but IMO the better readability is worth six bytes or so.
you can use an enum... its more readable and pretty
public enum daysOfWeek
{
Mon = 1, Tue = 2, Wed = 4, Thu = 8, Fri = 16, Sat = 32, Sun = 64
}
you can hide the complexity in a function: and it's better to bit-shift instead of dividing
private bool get_bit(int val, int idx)
{
return ((val >> idx) & 1) != 0;
}
精彩评论