PHP如何判断二进制数第几位是0或1

接口传过来一个二进制数,默认正常是0000000000000000,接口给的规则是从右数第1到第16位分别代表设备的通道1到通道16,0代表正常,1代表报警,比如传来0000000000000001就是通道1报警了,0000000000000011就是通道1和2都报警了,以此类推,我这边后台PHP需要判断了,如果有多个通道报警,还得判断哪几个报警了,给不同的值,有没有简单粗暴的方法
图片描述

这是我现在的方法,有啥简单粗暴的方法吗,如果有2个通道报警了,我得存两条不一样的数据,3个报警,3条不一样的数据,以此类推

阅读 5.5k
4 个回答

不要被表象迷惑了,这是字符串,按字符串处理。

$str = '0000000000000001';
echo $str[15];//输出 1

你对循环的理解需要加深下

$str = '0000000000011011';
$str = strrev($str);//字符顺序反转,强迫症使用
$warning = [];//用于存储产生报警的通道
$warning_msg = [
    1 => '漏电警报',
    2 => '温度1警报',
    3 => '温度2警报',
    //……4~16
];
for($i=0;$i<16;$i++){
    if($str[$i]==1) $warning[] = $i+1;
}

$data = [];
$list = [];
foreach($warning as $index){
    $list['info'] = $warning_msg[$index];
    $model->save($list);
}

需要位移(<<)和并操作(&)即可
如:一个数是10进制的 12=b'00001100
则:

php -r '$a=12; echo ($a & 1<<2) ."\n" ; echo ($a & 1<<3) ."\n";  echo ($a & 1<<4 )."\n";'

会输出
4
8
0

即某一位为1则输出大于零。

切割字符串,翻转数组,使用 array_keys 找到包含 1 的索引位置,因为索引是从0 开始的所以需要执行一下递增,即 +1 就得到了想要的.

clipboard.png

一般传输应该不会直接传2进制字符串。传到后端对的应该是一个整数,然后根据这个整数的二进制位做计算。
两种方式

  1. 转换成二进制字符串,然后遍历字符串的每一个字符,判断是否是1,是1则对应通道报警。
  2. 对1循环左移与输入整数做按位与运算,如果运算结果不为0,则对应通道报警。

推荐使用整数按位与运算,因为位运算速度在程序里是最快的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题