Я пробовал что-то подобное, это может быть полезно:
protected void C1_SelectionChanged(object sender, EventArgs e)
{
Label1.Text = "";
L1.Items.Add(C1.SelectedDate.ToShortDateString());
ListItem[] x = new ListItem[L1.Items.Count];
L1.Items.CopyTo(x, 0);
Session["x"] = x;
ListItem[] collection = (ListItem[])Session["x"];
foreach (var item in collection)
{
Label1.Text += item.Text + "</br>";
}
}
И еще один способ сделать это попробуйте:
List<DateTime> lb = new List<DateTime>();
lb.Add(C1.SelectedDate);
DateTime[] a = lb.ToArray();
lb.CopyTo(a, 0);
Session["x"] = a;
DateTime[] collection = (DateTime[])Session["x"];
foreach (var item in collection)
{
Label1.Text += item.ToShortDateString() + "</br>";
}
Тот же код будет работать на неподписанный символ. Цикл по всем битам, тестирующим их. Посмотрите это.
const unsigned char oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
unsigned char CountOnes(unsigned char x)
{
unsigned char results;
results = oneBits[x&0x0f];
results += oneBits[x>>4];
return results
}
Имейте массив, который знает число битов для 0 до 15. Добавьте результаты для каждого откусывания.
HACKMEM имеет этот алгоритм в 3 операциях (примерно переведенный в C):
bits = (c * 01001001001ULL & 042104210421ULL) % 017;
(ULL
должен вызвать 64-разрядную арифметику. Это необходимо, едва-едва... это вычисление требует 33-разрядных целых чисел.)
На самом деле можно заменить вторую константу 042104210021ULL
, так как Вы только считаете 8 битов, но это не выглядит как приятно симметричным.
Как это работает? Думать c
поразрядно, и помните это (a + b) % c = (a % c + b % c) % c
, и (a | b) == a + b
эквивалентность (a & b) == 0
.
(c * 01001001001ULL & 042104210421ULL) % 017
01 01001001001 01 1
02 02002002002 02000000000 1
04 04004004004 04000000 1
010 010010010010 010000 1
020 020020020020 020 1
040 040040040040 040000000000 1 # 040000000000 == 2 ** 32
0100 0100100100100 0100000000 1
0200 0200200200200 0200000 1
Если Вы не имеете 64-разрядную арифметику в наличии, можно разделить c
в откусывание и делают каждую половину, беря 9 операций. Это только требует 13 битов, таким образом с помощью 16-, или 32-разрядная арифметика будет работать.
bits = ((c & 017) * 0421 & 0111) % 7 + ((c >> 4) * 0421 & 0111) % 7;
(c * 0421 & 01111) % 7
1 0421 01 1
2 01042 01000 1
4 02104 0100 1
8 04210 010 1
Например, если c == 105 == 0b11001001
,
c == 0100
| 040
| 010
| 01 == 0151
* 01001001001001ULL == 0100100100100
| 040040040040
| 010010010010
| 01001001001 == 0151151151151
& 0421042104210421ULL == 0100000000
| 04000000000
| 010000
| 01 == 04100010001
% 017 == 4
c & 017 == 8 | 1 == 011
011 * 0421 == 8 * 0421 | 1 * 0421 == 04210 | 0421 == 04631
04631 & 0111 == 04210 & 0111 | 0421 & 0111 == 010 | 01 == 011
011 % 7 == 2
c >> 4 == 4 | 2 == 06
06 * 0421 == 4 * 0421 | 2 * 0421 == 02104 | 01042 == 03146
03146 & 0111 == 02104 & 0111 | 01042 & 0111 == 0100 | 01000 == 01100
01100 % 7 == 2
2 + 2 == 4
Посмотрите, что битовое жонглирование взламывает страницу: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
существует много хороших решений для этого.
Кроме того, эта функция в ее самой простой реализации довольно тривиальна. Необходимо не торопиться, чтобы изучить, как сделать это.
Как уже отвечено, стандартные способы считать биты также работают над неподписанными символами.
Пример:
unsigned char value = 91;
int bitCount = 0;
while(value > 0)
{
if ( value & 1 == 1 )
bitCount++;
value >>= 1;
}
Для целого числа, столь же маленького как неподписанный символ, Вы получаете лучшую производительность с помощью маленькой справочной таблицы.
Я знаю, какие алгоритмы количества населения Вы упоминаете. Они работают путем выполнения арифметики нескольких слов, меньших, чем целое число, сохраненное в регистре.
Эту технику называют SWAR (http://en.wikipedia.org/wiki/SWAR).
Для получения дополнительной информации я предлагаю, чтобы Вы проверили веб-сайт восхищения хакеров: www.hackersdelight.org. У него есть пример кода и записанный книга, которая объясняет эти приемы подробно.
неподписанный символ является "числом" просто тем же способом, которым 32-разрядное плавание или целое число являются "числом", что компилятор считает ими для представления, что изменения.
если Вы изображаете символ как его биты:
01010011 (8 битов);
можно считать биты набора путем выполнения следующего:
примите значение, позволяет, говорят, что x, и берут x % 2, остаток будет или 1 или 0. то есть, в зависимости от порядка байтов символа, левое или правое большая часть бита. накопите остаток в отдельной переменной (это будет получающимся числом битов набора).
затем>> (сдвиг вправо) 1 бит.
повторитесь, пока 8 битов не были смещены.
код c должен быть довольно прост реализовать из моего псевдокода, но в основном
public static int CountSetBits(char c)
{
int x = 0;
int setBits = 0;
while (x < 7)
{
setBits = setBits + c % 2;
c = c >> 1;
x = x + 1;
}
}