Используйте кумулятивные суммы:
select t.*,
sum(cases - closed) over (order by year) as state
from t;
Я считаю state
любопытным названием для кумулятивной суммы.
Я думаю, вам придется перевести это на это:
i & 1 == 1
i & 2 == 2
i & 4 == 4
и т.д ... Это использует побитовый оператор AND.
Когда вы используете побитовый оператор AND, этот оператор будет сравнивать двоичное представление двух заданных значений и возвращать двоичное значение, где установлены только те биты, которые также установлены в два операнда.
Например, когда вы делаете это:
2 & 2
Это сделает это:
0010 & 0010
И это приведет к:
0010
0010
&----
0010
Тогда, если вы сравните этот результат с 2 (0010 ), это, конечно, вернет истину.
Это делает побитовое И , а не логическое И.
Каждый из них в основном определяет, установлен ли один бит в i
например:
5 AND 4 = 4
5 AND 2 = 0
5 AND 1 = 1
(потому что 5 = двоичная 101, а 4, 2 и 1 - десятичные значения двоичной 100, 010 и 001 соответственно.)
Просто добавьте: Это называется битмасингом http://en.wikipedia.org/wiki/Mask_ (вычисления)
Для логического значения требуется только 1 бит. В реализации большинства языков программирования логическое значение занимает больше, чем один бит. В ПК это не будет большой тратой, но встроенные системы обычно имеют очень ограниченное пространство памяти, поэтому траты действительно значительны. Чтобы сэкономить место , логические значения упакованы вместе, таким образом, логическая переменная занимает всего 1 бит.
Вы можете думать о ней как о чем-то вроде операции индексации массива , с байтом (= 8 битов), похожим на массив из 8 логических переменных, так что, возможно, это ваш ответ: используйте массив логических значений.
(i и 16) / 16 извлекает значение (1 или 0) 5-го бита.
1xxxx and 16 = 16 / 16 = 1
0xxxx and 16 = 0 / 16 = 0
Подумайте об этом в двоичном коде, например
10101010
AND
00000010
дает 00000010
, то есть не ноль. Теперь, если первое значение было
10101000
, вы получите
00000000
, т. Е. Ноль.
Обратите внимание на дальнейшее деление, чтобы уменьшить все до 1 или 0.
И оператор выполняет «... побитовое соединение двух числовых выражений», которое отображается на «|» в C #. '`Является целочисленным делением , и эквивалентным в C # является /
при условии, что оба операнда имеют целочисленные типы.
Постоянные числа - это маски (представьте их в двоичном виде). Таким образом, код использует битовый оператор И для байта и маски и делит их на число, чтобы получить бит.
Например:
xxxxxxxx & 00000100 = 00000x000
if x == 1
00000x00 / 00000100 = 000000001
else if x == 0
00000x00 / 00000100 = 000000000
В C # использовать класс BitArray для непосредственного индексирования отдельных битов.
Установить отдельный бит i просто:
b |= 1 << i;
Кому сбросить отдельный бит i немного более неловко:
b &= ~(1 << i);
Имейте в виду, что как побитовые операторы, так и операторы сдвига стремятся преобразовать все в int
, что может неожиданно потребовать приведения. 1129140]
Я предпочитаю использовать шестнадцатеричное обозначение при битовом твидлинге (например, 0x10 вместо 16). Это имеет больше смысла, поскольку вы увеличиваете свою разрядность, так как 0x20000 лучше, чем 131072.
Как уже говорилось, это побитовое И, а не логическое И. Я вижу, что это было сказано довольно много раз до меня, но IMO объяснения не так легко понять.
Мне нравится думать об этом так:
Запишите двоичные числа друг под другом ( здесь я делаю 5 и 1):
101
001
Теперь нам нужно превратить это в двоичное число, где все 1 из 1-го числа, которое также во втором, передается, то есть - в этом случае:
001
В этом случае мы видим, что он дает тот же номер, что и 2-й номер, в котором эта операция (в VB) возвращает true. Давайте посмотрим на другие примеры (используя 5 в качестве i):
(5 и 2)
101
010
----
000
(неверно)
(5 и 4)
101
100
---
100
(верно)
(5 и 8)
0101
1000
----
0000
(неверно)
(5 и 16)
00101
10000
-----
00000
(неверно)
РЕДАКТИРОВАТЬ: и, очевидно, я упускаю всю суть вопроса - вот перевод на C #:
cbi[1].Checked = i & 1 == 1;
cbi[2].Checked = i & 2 == 2;
cbi[3].Checked = i & 4 == 4;
cbi[4].Checked = i & 8 == 8;
cbi[5].Checked = i & 16 == 16;