• 设备通道开启关闭状态


    设备有开和关两个状态,用0表示关、1表示开,不同设备类型通道数不同,目前通道数分8、16、24、32四种,以最简单的8通道来说,11111111 八个 1 表示8个通道全开,这个8位数其实可以看做一个二进制数字,每一位都有0和1两种值,每一位数都可以代表一个通道的状态,这个2进制转化为10进制就是:

    2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7

    = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128

    = 255

    顺便说一个不相关的事,其实 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 就等于 2^8 - 1,so easy

    那么如果要记录一个设备的8个通道全开,只要记录一个字段(比如ChannelStatus),值记录为 255 即可

    00000000 八个 0 ,这个就简单了,这个ChannelStatus字段值记录为 0 即可

    那么如果只有4号通道是开启的,其他通道都是关闭的改如何表示呢,很明显,2进制形式应该是 0000 1000 (为了方便看清楚位置,四位空格隔开),转为10进制就是:

    0 + 0 + 0 + 2^3 + 0 + 0 + 0 + 0

    = 8

    通过上述的讲解,很容易发现,如果通道状态是关闭的,它对ChannelStatus这个字段的值的增量是 0 ,如果是开启的,它对ChannelStatus这个字段的值的增量是 2 的 (通道号 -1) 次方,根据这个规律,ChannelStatus的计算方式如下:

    ChannelStatus  = 0;

    for (Channel ch : channelList) {

      if (ch 是开启的) {

        int chstu = (int) Math.pow(2, ch的通道号 - 1);

        ChannelStatus += chstu 

      }

    }

    下面介绍下反向计算:

    如果已知ChannelStatus的值,如何知道某个通道是什么状态呢?

    有人可能会想,这个简单,把ChannelStatus的值转为2进制,比如12,二进制就是 0000 1100 ,很明显3号、4号通道是开启的,这个思路是对的,只是这个3号、4号是开启的是你的肉眼判断出来的,如何让代码来判断出这个结果呢?

    又有人可能会说,转成字符串,拆分成数组,然后for循环判断就好了,行也是行的,这里我要介绍另一种判断方式,这里设计到二进制的与计算,0和0或者1相与都是0,只有1和1相与结果是1

    那么 判断通道3是否开启,只需要用 ChannelStatus的值,与 0000 0100相与,0000 0100只有第3位是1,那么其他位无论与0还是1相与都是0,唯独这个第3位,如果与1相与是1,与0相与是0,那么 0000 0100 无论和什么数相与,结果只有两种,0000 0000 或者 0000 0100 ,也就是说只要结果不是0(或者结果和该通道的2进制值相当),就可以判断该通道是开启的,代码表达如下:

    ChannelStatus  是一个已知数

    for (Channel ch : channelList) {

      int chstu = (int) Math.pow(2, ch的通道号 - 1);

      if ((chstu & ChannelStatus) == chstu) { // 或者判断 (chstu & ChannelStatus) != 0

        ch.set状态为开启

      }

    }

    完结!

  • 相关阅读:
    Array的 map() 和 reduce()
    欧几里得算法求解最大公约数
    JavaScript Function
    JavaScript Hoisting(提升)
    activemq的事务消息
    Spring整合Activemq
    10张图带你深入理解Docker容器和镜像
    Thread类的interrupt方法
    简单工厂、工厂方法、抽象工厂笔记
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/LcxSummer/p/12893847.html
Copyright © 2020-2023  润新知