IF и битовые выражения

Shoroh

Новичок
На входе в обработчик переменная $kluch вида hex (например 34), далее преобразовал ее в переменную $hexbin (получается 00110100), т.е. бинарный формат, единицы и ноли.

Затем необходимо проанализировать переменную $hexbin по наличию флагов в нужных позициях, и если стоит единица, то вернуть нужную фразу.

Набросал такой код:

PHP:
		$hexbin = preg_replace('#[0-9A-F]#sei','sprintf("%04b",0x$0)',$kluch);
			$str = "";
			if($hexbin & 1<<0){
				$str .= "Virtual cassette type 2 is low on bills";
			}
			if($hexbin & 1<<1){
				$str .= "Virtual cassette type 1 is low on bills";
			}
			if($hexbin & 1<<2){
				$str .= "Self-Test command";
			}
			if($hexbin & 1<<3){
				$str .= "Fatal malfunction INOP flag set";
			}
			if($hexbin & 1<<4){
				$str .= "Pick fail occurred";
			}
			if($hexbin & 1<<5){
				$str .= "Must be always 0";
			}
			if($hexbin & 1<<6){
				$str .= "Virtual cassette type 4 is low on bills";
			}
			if($hexbin & 1<<7){
				$str .= "Virtual cassette type 3 is low on bills";
			}
			echo ($str);
Сперва обрадовался, вроде работает, но потом заметил косяк. По идее, если ввести FF, то в переменной $str должны оказаться все выше перечисленные фразы. На практике этого не происходит, возвращаются почему-то всего пять фраз, как будто бы ввели не 1111 1111, а 1100 0111, т.е. флаги в позициях 16, 32 и 64 пропустились.

Такие же глюки происходят и с другими значениями $kluch, которые на выходе подразумевают вывод более пяти единиц (и значит более пяти фраз).

Не понимаю в чем дело, если кто знает — буду рад объяснению своей ошибки.
 

Вурдалак

Продвинутый новичок
Ты путаешь символы (графическое представление) «0» и «1» с реальными битами.

Чтобы было яснее, посмотри в таблице ASCII что ты должен увидеть в $hexbin, если бы делал правильно. Тебе нужна функция pack().
 

ksnk

прохожий
PHP:
if($hexbin{0}==1){ // 0 - позиция в строке
             $str .= "Virtual cassette type 2 is low on bills";
}
Нужно понять, откуда берутся эти флаги (34), где они хранятся.
 

Shoroh

Новичок
Тебе нужна функция pack().
К сожалению не нашел в php как явно задать тип "binary", поэтому делал интуитивно. Почитал про pack, кажется это должно помочь, спасибо.


PHP:
if($hexbin{0}==1){ // 0 - позиция в строке
             $str .= "Virtual cassette type 2 is low on bills";
}
Нужно понять, откуда берутся эти флаги (34), где они хранятся.
Значение вводит пользователь в форме (там я на jquery ограничиваю ввод только hex). Затем передается в обработчик на php.

Не знал, что строка в php это массив. Стало полегче, сдела все намного проще:

PHP:
			$hexbin = preg_replace('#[0-9A-F]#sei','sprintf("%04b",0x$0)',$kluch);
			if($hexbin[0] == 1){
				$str .= "Virtual cassette type 2 is low on bills";
			}
			if($hexbin[1] == 1){
				$str .= "Virtual cassette type 1 is low on bills";
			}
			if($hexbin[2] == 1){
				$str .= "Self-Test command";
			}
			if($hexbin[3] == 1){
				$str .= "Fatal malfunction INOP flag set";
			}
			if($hexbin[4] == 1){
				$str .= "Pick fail occurred";
			}
			if($hexbin[5] == 1){
				$str .= "Must be always 0";
			}
			if($hexbin[6] == 1){
				$str .= "Virtual cassette type 4 is low on bills";
			}
			if($hexbin[7] == 1){
				$str .= "Virtual cassette type 3 is low on bills";
			}
			echo ($str);
Всем спасибо, все заработало )
 

Beavis

Banned
На входе в обработчик переменная $kluch вида hex (например 34), далее преобразовал ее в переменную $hexbin (получается 00110100), т.е. бинарный формат, единицы и ноли.

Затем необходимо проанализировать переменную $hexbin по наличию флагов в нужных позициях, и если стоит единица, то вернуть нужную фразу.

Набросал такой код:

PHP:
		$hexbin = preg_replace('#[0-9A-F]#sei','sprintf("%04b",0x$0)',$kluch);
в своем начальном варианте просто замени это на $hexbin = hexdec($kluch);
 
Сверху