creator中关于位运算符的使用

前言:

<<
运算规则:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
语法格式:
  需要移位的数字 << 移位的次数
  例如: 3 << 2,则是将数字3左移2位
  计算过程:
  3 << 2
  首先把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,则转换为十进制是12.数学意义:
  在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以21次方,左移n位就相当于乘以2的n次方。

>>
运算规则:按二进制形式把所有的数字向右移动对应巍峨位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1.
  语法格式:
  需要移位的数字 >> 移位的次数
  例如11 >> 2,则是将数字11右移2位
  计算过程:11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010.转换为十进制是2.数学意义:右移一位相当于除2,右移n位相当于除以2的n次方。

正常情况
有若干个状态,我们使用一个数组来保存正在使用的状态,
前期判断逻辑 :
当需要某个状态时,就往数组中添加
中期处理逻辑:
拿到使用中的状态,去做一些骚操作,做完以后,从数组中删除掉该状态
看一段c语言的代码
而下面的实现是,状态使用左移位数来区分,数组采用一个整数来表示,这样代码执行效率高,具体原理请看下面的代码

/*
  左移运算:就是乘以2
  右移运算:就是除以2取整
  */
  for (int i = 0; i <1; i++)
  {
	  //下面是六种状态
	  //状态会有不同 通过依次左移来表示状态索引的唯一性
	  int sb1 = 1 << i;    //玩手机 1
	  int sb2 = 1 << i+1;  //吃东西 2
	  int sb3 = 1 << i+2;  //踩刹车 4
	  int sb4 = 1 << i+3;  //微笑   8 
	  int sb5 = 1 << i+4;  //踩油门 16
	  int sb6 = 1 << i+5;  //打左转向灯 32

	  //添加状态
	  //状态之间使用|这个运算符连接
	  //不要在意这个|运算符的操作结果,而是把它看成状态之间的连接来看
	  //从p1到p6你可以理解不同的状态在添加,满足交换律,交换律这个非常重要
	  //从宏观的角度看,我们的每一个状态都是数组的一个item,下面的|操作就好像在往p这个数组中插入元素
	  //只要不插入相同的元素,那么插入的位置可以随意组合
	  int p1 = sb1;
	  int p2 = sb1 | sb2;
	  int p3 = sb1 | sb2 | sb3;
	  int p4 = sb1 | sb2 | sb3 | sb4;
	  int p5 = sb1 | sb2 | sb3 | sb4 |sb5;
	  int p6 = sb1 | sb2 | sb3 | sb4 | sb5 | sb6;

	  printf("s----%d---%d---%d---%d---%d\n", sb1, sb2, sb3, sb4, sb5, sb6);
	  printf("~s----%d---%d---%d---%d---%d\n",~sb1, ~sb2 , ~sb3 , ~sb4 , ~sb5,~sb6);


	  /*
	   删除状态 相当于从p这个数组中删除状态
		 下面的操作会发现下面的等式成立
		 p5 == p6&~sb6
	 */
	  printf("删除sb6状态退回到p5合集状态---%d----%d-\n", p5, p6&~sb6);

	  //状态比较
	  //做&运算 不要在意计算结果,从宏观的角度看
	  /*
	    p1&p2:p1含有sb1状态,p2含有sb1和sb2两种状态,所以结果就是(sb1)
		p2&p3:p2含有sb1和sb2两种状态,p3含有sb1,sb2,sb3三种状态,所以结果就是(sb1|sb2)
		...依次类推
	  */
	  printf("&----%d---%d---%d---%d--%d\n", p1 & p2, p2 & p3, p3 & p4, p4 & p5, p5 & p6);
	 
	  //做|运算 不要在意计算结果,从宏观的角度看
	   /*
		 p1|p2:p1含有sb1状态,p2含有sb1和sb2两种状态,所以结果就是(sb1|sb2)
		 p2|p3:p2含有sb1和sb2两种状态,p3含有sb1,sb2,sb3三种状态,所以结果就是(sb1|sb2|sb3)
		 ...依次类推
	   */
	  printf("|----%d---%d---%d---%d--%d\n",p1|p2,p2|p3,p3|p4,p4|p5,p5|p6);
	  /*
	  总结做上面的状态比较,如果发现比较的两边状态数组,没有一个状态相等,那比较结果就为0
	  */
	 
  }
  /*
  下面是一个测试 就是对于一个整数1进行0-99次左移,每一次左移的结果都与整数1左移3位的结果进行&操作
  发现必须都是1<<3,其结果才是8,其余都是0
  这里的int所占字节数为4,也就是说最大移动31位,还有1位表示正负
  所以我们的移动位数不应该超过32位,因为你超过了int所代表的内存就没办法表示你的数据了,它就会去自动的截取
  它认为有效的位移数是(n = input%32);
  */
  for (int i = 0; i <31; i++)
  {
	  int s1 = 1 << 3;
	  int s2 = 1 << i;
	  printf("|&-----%d---%d------%d------%d\n", s1&s2, s1 | s2,i,s2);
  }

其实在我们的游戏引擎中就用到了这个写法
一个节点会有缩放,旋转,平移这三种基本的变换,也会有节点颜色,透明度等状态的变化,我们姑且认为就是这五种状态,游戏都是一帧一帧运行的,所以你频繁改变某一个状态,只会到一帧刷新的时间才会生效,游戏处理每一个节点的变化,就是根据节点的状态来进行的,到了一帧的刷新时间的时候,引擎会去访问根节点,从根节点开始访问整棵树的节点,对每一个节点,拿到他的状态变化,根据每一个变化进行相应的数据调整,而存储这个状态变化的就是一个整数而不是数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值