当前位置: 首页 > news >正文

一个byte表示多个bool属性的功能

如何实现用一个byte表示多个bool属性的功能?
用一个byte表示多个bool属性,本质是利用二进制位(bit) 的特性 ——1 个byte包含 8 个二进制位(bit0~bit7),每个位可以表示一个bool值(0 表示false,1 表示true)。这种方式能极大节省内存,尤其适合需要存储大量bool属性的场景(比如你的Pixel类)。
一、核心原理:把 byte 当 “8 个开关的面板”
想象一个byte是一个有 8 个开关的面板,每个开关只有 “开(1)” 和 “关(0)” 两种状态:
第 1 个开关(bit0):控制bo属性;
第 2 个开关(bit1):控制mark属性;
第 3 个开关(bit2):控制isLamp属性;
... 以此类推,最多可以控制 8 个bool属性。
例如:byte值为 5(二进制是 00000101),表示:
bit0=1 → bo=true;
bit1=0 → mark=false;
bit2=1 → isLamp=true;
其他位 = 0 → 对应属性为false。
二、具体实现:用位运算操作 “开关”
需要 4 个核心位运算操作:置位(开)、清位(关)、查位(读状态)、反转位(切换状态)。下面结合代码示例说明(以Pixel类的bo、mark、isLamp三个属性为例):
步骤 1:定义位标记(哪个位对应哪个属性)
先给每个bool属性分配一个 “位索引”(0~7),用常量表示:
csharp
public struct Pixel
{
// 定义每个属性对应的位(0~7)
private const byte BoBit = 0;      // bit0 → 对应bo属性
private const byte MarkBit = 1;    // bit1 → 对应mark属性
private const byte IsLampBit = 2;  // bit2 → 对应isLamp属性

    // 用一个byte存储所有位状态(8个开关的总状态)
private byte _flags;  // 核心存储变量,初始值0(所有位为0)
}
步骤 2:实现 “查位”(读取 bool 值)
判断某个位是否为 1(true),用与运算(&):
csharp
public struct Pixel
{
// 读取bo属性:判断bit0是否为1
public bool bo => (_flags & (1 << BoBit)) != 0;

    // 读取mark属性:判断bit1是否为1
public bool mark => (_flags & (1 << MarkBit)) != 0;

    // 读取isLamp属性:判断bit2是否为1
public bool isLamp => (_flags & (1 << IsLampBit)) != 0;

    // 其他代码...
}
原理:1 << n 会生成一个 “第 n 位为 1,其他位为 0” 的数字(比如1 << 2是100二进制 = 4),与_flags做&运算后,如果结果非 0,说明第 n 位是 1。
步骤 3:实现 “置位”(设置为 true)
把某个位设为 1(true),用或运算(|):
csharp
public struct Pixel
{
// 设置bo为true:将bit0置为1
public void SetBoTrue() => _flags |= (byte)(1 << BoBit);

    // 设置mark为true:将bit1置为1
public void SetMarkTrue() => _flags |= (byte)(1 << MarkBit);

    // 设置isLamp为true:将bit2置为1
public void SetIsLampTrue() => _flags |= (byte)(1 << IsLampBit);

    // 其他代码...
}
原理:1 << n 生成第 n 位为 1 的数字,与_flags做|运算后,第 n 位会被强制设为 1(其他位不变)。
步骤 4:实现 “清位”(设置为 false)
把某个位设为 0(false),用与非运算(&~):
csharp
public struct Pixel
{
// 设置bo为false:将bit0清为0
public void SetBoFalse() => _flags &= (byte)~(1 << BoBit);

    // 设置mark为false:将bit1清为0
public void SetMarkFalse() => _flags &= (byte)~(1 << MarkBit);

    // 设置isLamp为false:将bit2清为0
public void SetIsLampFalse() => _flags &= (byte)~(1 << IsLampBit);

    // 其他代码...
}
原理:~(1 << n) 生成 “第 n 位为 0,其他位为 1” 的数字,与_flags做&运算后,第 n 位会被强制设为 0(其他位不变)。
步骤 5:实现 “反转位”(true→false 或 false→true)
切换某个位的状态,用异或运算(^):
csharp
public struct Pixel
{
// 切换bo的状态(true→false,false→true)
public void ToggleBo() => _flags ^= (byte)(1 << BoBit);

    // 其他属性同理...
}
原理:1 << n 与_flags做^运算后,第 n 位会反转(0→1,1→0),其他位不变。
三、使用示例:操作多个 bool 属性
csharp
// 创建一个Pixel实例
Pixel p = new Pixel();

// 设置属性
p.SetBoTrue();       // bo=true(bit0=1)
p.SetMarkTrue();     // mark=true(bit1=1)
p.SetIsLampFalse();  // isLamp=false(bit2=0)

// 此时_flags的二进制是 00000011(十进制3)

// 读取属性
Console.WriteLine(p.bo);       // 输出:True
Console.WriteLine(p.mark);     // 输出:True
Console.WriteLine(p.isLamp);   // 输出:False

// 切换状态
p.ToggleBo();                  // bo从true→false(bit0=0)
Console.WriteLine(p.bo);       // 输出:False
四、优势与注意事项
优势:
节省内存:1 个byte存储 8 个bool(原本 8 个bool占 8 字节,现在只需 1 字节,节省 87.5%);
提高效率:CPU 处理位运算速度极快,且byte占用内存小,缓存利用率更高。
注意事项:
最多 8 个属性:1 个byte只能存 8 个bool,超过需要用ushort(16 位)、uint(32 位)等;
调试稍复杂:直接打印_flags是数字(如 3),需转换为二进制查看(可用Convert.ToString(_flags, 2));
封装必要性:必须通过方法(如SetBoTrue)操作,避免直接修改_flags导致逻辑混乱。
总结
用 1 个byte表示多个bool,本质是 “用二进制位当开关”,通过位运算(&、|、~、^)操作这些开关。这种方式在需要大量bool属性的场景(如你的像素类)中非常实用,既能节省内存,又能提升性能。

http://www.dtcms.com/a/348031.html

相关文章:

  • 高并发AI服务部署方案:vLLM、TGI、FastChat性能压测报告
  • CSS 进阶用法
  • Read View是实现MVCC的三大前提之一,那么它是在什么时候建立的
  • frida安装配置及其使用方法
  • 一个奇怪的问题-Python会替代Java吗?技术语言之争的真相-优雅草卓伊凡
  • Java 大视界 -- Java 大数据在智能交通智能公交系统中的乘客流量预测与车辆调度优化
  • 程序里的依赖和中间件的依赖冲突,怎么解决
  • Docling:一个基于AI驱动的免费文档解析工具
  • Python性能优化实战(二):让循环跑得比博尔特还快
  • [身份验证脚手架] 应用布局如何构建
  • 初学python的我开始Leetcode题-16
  • CTFshow系列——命令执行web49-52
  • assert使用方法
  • Redis 高可用开发指南
  • 力扣594:最和谐子序列
  • 客流特征识别误报率↓76%!陌讯多模态时序融合算法在智慧零售的实战解析
  • Tesla智能座舱域控制器(MCU)的系统化梳理
  • 【网络运维】Shell 脚本编程:if 条件语句
  • 【40页PPT】数字工厂一体化运营管控平台解决方案(附下载方式)
  • Spark04-MLib library01-机器学习的介绍
  • SNMP 协议的总结
  • 每日算法题【链表】:相交链表、环形链表、环形链表II
  • 鸿蒙分布式计算实战:用 ArkTS+Worker 池落地可运行任务管理 Demo,从单设备到跨设备全方案
  • [二维前缀和]1277. 统计全为 1 的正方形子矩阵
  • HarmonyOS实战(DevEco AI篇)—深度体验DevEco CodeGenie智能编程助手
  • Function + 枚举 + Map:轻量路由器的最佳实践
  • ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘192.168.24.96‘ (10060)
  • 基于Java、GeoTools与PostGIS的对跖点求解研究
  • 大数据毕业设计选题推荐:基于Spark+Django的学生创业数据分析可视化系统详解 毕业设计/选题推荐/深度学习/数据分析/数据挖掘/机器学习/随机森林
  • 网络编程socket-Udp