如何用最短位运算实现方向枚举的无冲突对称反转
实现方向枚举的位运算反转
嘿,这个问题我之前也琢磨过!用位运算来实现这种对称方向的反转确实比三元表达式更简洁,咱们一步一步来拆解怎么搞定它。
首先先回顾一下你的方向枚举定义:
public enum Direction { None = 0, Up = 1 << 1, Down = 1 << 2, Left = 1 << 3, Right = 1 << 4, UpLeft = Up | Left, UpRight = Up | Right, DownLeft = Down | Left, DownRight = Down | Right }
核心思路:利用异或实现对称位的互换
我们的目标是让Up↔Down、Left↔Right,None保持不变。观察位值可以发现:
Up(1<<1=2)和Down(1<<2=4)的组合掩码是Up|Down=6,对任意垂直分量和这个掩码异或,就能实现互换:2^6=4(Up→Down),4^6=2(Down→Up)Left(1<<3=8)和Right(1<<4=16)的组合掩码是Left|Right=24,同理,8^24=16(Left→Right),16^24=8(Right→Left)
基于这个思路,我们可以写出极简的位运算实现:
public Direction Inverse(Direction d) => d == Direction.None ? d : ((d & (Direction.Up | Direction.Down)) ^ (Direction.Up | Direction.Down)) | ((d & (Direction.Left | Direction.Right)) ^ (Direction.Left | Direction.Right));
代码解释
- None的特殊处理:如果输入是
None,直接返回自身,符合需求。 - 垂直分量反转:
d & (Up|Down)提取出方向中的垂直部分(Up或Down),再和Up|Down异或,完成Up和Down的互换。 - 水平分量反转:同理,
d & (Left|Right)提取水平部分,和Left|Right异或完成Left和Right的互换。 - 合并结果:将反转后的垂直和水平分量按位或,得到最终的反转方向。
验证一下效果
Up→((2 &6)^6)|0 = (2^6)=4 → Down,正确UpLeft→((2&6)^6)|((8&24)^24) =4|16=20 → DownRight,正确Right→0|((16&24)^24)=16^24=8 → Left,正确
这个实现完全用位运算完成,没有多余的条件判断(除了None的必要处理),比三元表达式更高效简洁,而且不会产生冲突方向(因为原枚举的合法输入本身就没有同时包含Up+Down或Left+Right的情况)。
内容的提问来源于stack exchange,提问作者Enfyve
相关产品推荐
相关产品推荐

