• java 二进制 位运算符


    位运算符 & | ~ ^

    & : 对两个二进制数按位做与运算,即 1 & 0 = 0; 1 & 1 = 1; 0 & 0 = 0;
    | : 对两个二进制数按位做或运算,即 1 & 0 = 1; 1 & 1 = 1; 0 & 0 = 0;
    ~ : 对一个二进制数按位取反,即 ~1 = 0; ~0 = 1;
    ^ : 对两个二进制数按位做异或运算,即 1 ^ 1 = 0; 1 ^ 0 = 1, 0 ^ 0 = 0; 相同取0,不同取1

    另:

    1)
        十进制-1 的二进制表示,为书写简单假设 这里的10进制数字是16位的int类型,以下十进制用D()表示
        D(1) = 0000 0000 0000 0001
        D(-1) 原码 = 1000 0000 0000 0001
        D(-1) 补码 = 1111 1111 1111 1111 原码的基础上除符号位以外按位取反后+1
    2) 用R表示任意数
        2.1) 0 & R = 0; 1 & R = R; R & R = R;
        2.2) 1 | R = 1; 0 | R = R; R | R = R;
        2.3) 1 ^ R = ~R; 0 ^ R = R; R ^ R = 0;

    实例
    商城在对商品做分析的时候,需要根据用户行为对商品打一些标记,有许多标记就是‘是/否’的一种逻辑,
    假设需要打标记:1 是否促销  2 正品 3 参加双十一 4 参加双十二 等等
    提供一个比较好玩的方法
    既然这些标记都是‘是否’的取值逻辑,即是否打这个标记,那么我们就可以用二进制来表示。
    设定一个int字段,这个字段值的特定位表示特定的tag,取值1表示打标记,取值0表示不打标记

    package Binary;
    
    public class BinaryTag {
        static class Goods {
            private String name;
            private int tag;
            
            public Goods() {}
            
            public Goods(String name, int tag) {
                this.name = name;
                this.tag = tag;
            }
            
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public int getTag() {
                return tag;
            }
            public void setTag(int tag) {
                this.tag = tag;
            }
        }
        class Tag {
            public final static int None = 0; // 没有标记
            public final static int All = -1; // 全部标记 1111 …… 1111
            public final static int Promotion = 1; // 促销标记 0001
            public final static int Genuine = 2; // 正品标记 0010
            public final static int Double11 = 4; // 双十一 0100
            public final static int Double12 = 8; // 双十二 1000
        }
        /**
         * @param args
         */
        public static void main(String[] args) {
            Goods nike = new Goods("Nike", Tag.None);
            
            System.out.print("标为正品;");
            mark(nike, Tag.Genuine);
            System.out.print("参加促销;");
            mark(nike, Tag.Promotion);
            System.out.print("参加双十一;");
            mark(nike, Tag.Double11);
            System.out.println("不参加双十二;");
            clearMark(nike, Tag.Double12);
            descGoods(nike);
            
            System.out.println("不促销了,也不参加双十一了;");
            clearMark(nike, Tag.Promotion + Tag.Double11);
            descGoods(nike);
            
            System.out.println("反转双十一和双十二的标记;");
            reverseMark(nike, Tag.Double11 + Tag.Double12);
            descGoods(nike);
            
            System.out.println("反转双十一和双十二的标记;");
            reverseMark(nike, Tag.Double11 + Tag.Double12);
            descGoods(nike);
            
            System.out.println("添加全部标记;");
            markAll(nike);
            descGoods(nike);
            
            System.out.println("清除所有标记;");
            clearAllMark(nike);
            descGoods(nike);
        }
        /**
         * 添加某种标记
         * @param goods
         * @param tag
         */
        public static void mark(Goods goods, int tag) {
            int oldTag = goods.getTag();
            // 将tag位 置为1 引用 [2.2) 1 | R = 1; 0 | R = R; R | R = R;]
            int newTag = (oldTag | tag);
            goods.setTag(newTag);
        }
        /**
         * 打上所有的标记
         * @param goods
         */
        public static void markAll(Goods goods) {
            goods.setTag(Tag.All);
        }
        /**
         * 消除商品tag
         * @param goods
         * @param tag
         */
        public static void clearMark(Goods goods, int tag) {
            int oldTag = goods.getTag();
            int newTag = (oldTag & (~tag));
            goods.setTag(newTag);
        }
        /**
         * 消除全部标记
         * @param goods
         */
        public static void clearAllMark(Goods goods) {
            goods.setTag(Tag.None);
        }
        /**
         * 对指定标记进行反转
         * @param goods
         * @param tag
         */
        public static void reverseMark(Goods goods,int tag) {
            int oldTag = goods.getTag();
            int newTag = (oldTag ^ tag);
            goods.setTag(newTag);
        }
        /**
         * 是否打了这种标记
         * @param goods
         * @param tag
         * @return
         */
        public static boolean isTaged(Goods goods, int tag) {
            int oldTag = goods.getTag();
            return tag == (oldTag & tag);
        }
        
        public static void descGoods(Goods goods) {
            System.out.print(goods.getName()+":");
            System.out.print((isTaged(goods, Tag.Promotion)?"":"不") + "参加促销;");
            System.out.print((isTaged(goods, Tag.Genuine)?"":"不") + "是正品;");
            System.out.print((isTaged(goods, Tag.Double11)?"":"不") + "参加双十一;");
            System.out.print((isTaged(goods, Tag.Double12)?"":"不") + "参加双十二;");
            System.out.println("
    ");
        }
    }

     Console:

    标为正品;参加促销;参加双十一;不参加双十二;
    Nike:参加促销;是正品;参加双十一;不参加双十二;
    
    不促销了,也不参加双十一了;
    Nike:不参加促销;是正品;不参加双十一;不参加双十二;
    
    反转双十一和双十二的标记;
    Nike:不参加促销;是正品;参加双十一;参加双十二;
    
    反转双十一和双十二的标记;
    Nike:不参加促销;是正品;不参加双十一;不参加双十二;
    
    添加全部标记;
    Nike:参加促销;是正品;参加双十一;参加双十二;
    
    清除所有标记;
    Nike:不参加促销;不是正品;不参加双十一;不参加双十二;
  • 相关阅读:
    MIME 部分扩展名与类型对应
    sql server 表变量、表类型、临时表
    SqlBulkCopy使用注意事项
    SQL Server为啥使用了这么多内存?
    SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现
    DQL、DML、DDL、DCL的概念与区别
    IIS解决CPU和内存占用率过高的问题
    SQL Server 表变量和临时表的区别
    I Count Two Three(打表+排序+二分查找)
    AC自动机入门经典题目(两种表达方式)
  • 原文地址:https://www.cnblogs.com/erbin/p/4432998.html
Copyright © 2020-2023  润新知