20 апреля 2010 г.

Проверка установленности бита без битовых операций (например, в xslt), или xslt bitwise operations.

Потребовалось в xslt проверить установку определённого битового флага, а битовых операций нет. Что делать? Без паники! Воспользуемся трюком (громко сказано) с делением:
bitset(x, n) := (x div 2^n) mod 2 == 1
, где div - деление нацело, mod - остаток от деления.

Неочевидность здесь кажущаяся, секрет в отбрасывании ненужных бит справа и проверки первого бита из остатка. Вкратце: пусть у нас есть вектор и нам надо проверить 13-й бит (нумерация с нуля).
flags
15                0
abXx xxxx xxxx xxxx

8192
  13
0010 0000 0000 0000
остаток от деления нацело:
abX

Ну и очевидно, что нужный нам бит (последний в получившемся числе) - это отстаток от деления на 2 этого числа, что проверяется через abX mod 2 = 1.

Или вот деление в бинарном коде:
0101010101010101÷0010000000000000=010,101010101
0101010101010101 div 0010000000000000=010

Итак, в xslt проверка установленности бита будет так (2^13 = 8192):

<xsl:if test="floor(/data/@flags div 8192) mod 2 = 1">
...
</xsl:if>

2 комментария:

  1. А для чего тебе в xslt понадобилась проверка флага?

    ОтветитьУдалить
  2. Антон, ну всякое бывает. У нас, например, на xslt строится вся веб-морда, ну, сам видел какая. Так вот, конкретно этот случай - в исходном xml есть инфа о текущем договоре, и в нём - флаг из 64 бит, показывающий вхождение этого догвора в некоторые из 64 групп. Ну, видимо понадобилось определить вхождение в какую-то группу, чтобы сделать какое-то отдельное действие или что-то типа того, уже позабыл чего там надо было товарищу. С одной стороны, все эти действия можно (и скорее правильнее) делать на стороне контроллера, при формировании xml, но вот например в нашем случае пользователи нашей системы имеют доступ только к шаблонам. Ну и мало ли что ещё бывает)

    ОтветитьУдалить