详解位示图计算方法、代码

位示图

  • 位示图的核心思想
  • 计算过程与位操作
    • 假设问题场景:
  • 实际操作与计算:
    • 1. 位示图的初始化
    • 2. 设置某一位(标记资源占用)
    • 3. 清除某一位(释放资源)
    • 4. 查询某一位(检查资源状态)
  • 示例
    • 问题描述:
    • 关键参数:
    • 位示图大小的计算步骤:
      • 1. 计算磁盘上的物理块数量:
      • 2. 计算位示图的总位数:
      • 3. 计算位示图的字节数:
    • 计算实例:
      • 参数设定:
      • 步骤1:计算物理块数量
      • 步骤2:计算位示图总位数
      • 步骤3:计算位示图的字节数
    • 优化讨论:字长的影响
    • 完整示例:
      • 结果解释:
  • 综合示例:
    • 详细讲解每一步:
  • 理论优势与应用场景
  • 练题
    • 已知参数:
    • 计算过程:
      • 1. 计算磁盘的物理块数量
      • 2. 计算位示图总位数
      • 3. 计算位示图的字节数
      • 4. 计算位示图的字数
    • 结论:

位示图(Bit-Map)是一种非常紧凑和高效的位操作技术,特别适用于管理系统资源或者表示大规模数据的某种状态。在位示图中, 每一位都代表某个资源或元素的状态。为了更生动地理解其工作原理,我们可以从理论计算和位运算的角度进行深入探讨,并通过详细的示例展示如何使用位示图来解决问题。

位示图的核心思想

位示图的基本思想是将每一位(bit)作为一种状态标识,状态可以是“已占用”或“未占用”,或者“存在”或“不存在”。位示图最常用于两个状态的管理,因为每一位(bit)只能存储0或1。

计算过程与位操作

假设我们要管理一个系统中8个资源块的使用情况。最简单的方法是使用一个8位的变量,每个位代表一个资源块。位的设置和清除通常通过位运算来完成。

假设问题场景:

我们有一个系统资源,共8个块,编号从0到7。我们需要跟踪哪些块已经被使用,哪些块是空闲的。使用位示图,我们可以紧凑地用8个bit来表示这8个资源的状态。

实际操作与计算:

1. 位示图的初始化

位示图可以用一个字节(8位)表示,初始状态下所有位都是0,表示资源未被占用。

unsigned char bitmap = 0b00000000; // 全部位为0,表示资源未使用

位示图的初始值为 0b00000000。这里使用二进制表示法 0b 表示8位都为0。

2. 设置某一位(标记资源占用)

当我们想要标记第2号块已经被使用,可以通过**位“或”运算(OR运算)**来设置某一位为1。

bitmap |= (1 << 2); // 设置第2位
  • 1 << 2 将1左移两位,得到 0b00000100,这是只将第2位设为1的掩码(mask)。
  • bitmap |= 0b00000100 将位示图与这个掩码做“或”运算,结果是将第2位设置为1而不影响其他位。

理论计算
bitmap = 0b00000000 | 0b00000100 = 0b00000100
此时,位示图的值变为 0b00000100,表示第2号块被占用。

3. 清除某一位(释放资源)

假设我们要释放第2号块,将该块标记为可用。我们使用**位“与”运算(AND运算)**与取反(NOT)来清除位。

bitmap &= ~(1 << 2); // 清除第2位
  • 1 << 2 得到 0b00000100
  • ~(1 << 2) 取反得到 0b11111011,这是清除第2位的掩码。
  • bitmap &= 0b11111011 将位示图和掩码做“与”运算,清除第2位为0。

理论计算
bitmap = 0b00000100 & 0b11111011 = 0b00000000
此时,位示图的值恢复为 0b00000000,表示第2号块已释放。

4. 查询某一位(检查资源状态)

我们可以通过位“与”运算检查某一位的状态,看看某个资源是否被使用。

int is_set = bitmap & (1 << 2); // 查询第2位是否为1
  • 1 << 2 得到 0b00000100,然后通过位“与”运算,检查第2位是否为1。

理论计算
is_set = 0b00000000 & 0b00000100 = 0b00000000
返回值为0,表示第2位(第2号块)未被使用。
为了更详细地说明如何通过位示图管理资源,以及如何计算位示图的大小,我们需要引入计算机系统的一些关键参数,比如字长磁盘容量、和物理块大小。接下来,我们通过一个实际的计算示例,演示如何根据这些参数计算位示图的大小。

示例

问题描述:

假设我们有一个磁盘系统,它的磁盘容量是已知的,并且该磁盘被划分为若干个物理块。为了管理这些物理块的使用情况,我们使用位示图。我们需要根据系统的磁盘容量和每个物理块的大小来计算位示图的大小。

关键参数:

  1. 磁盘容量(Total Disk Capacity):磁盘的总容量,用字节(Bytes)表示。
  2. 物理块大小(Block Size):磁盘中每个物理块的大小,通常以字节(Bytes)表示。
  3. 位示图大小(Bitmap Size):位示图所占用的空间大小,用字节表示。
  4. 字长(Word Size):计算机系统中,CPU能够一次处理的位数,常见的字长有32位和64位。字长影响位示图的读取和存储效率,但不会直接影响位示图所需的大小。

位示图大小的计算步骤:

1. 计算磁盘上的物理块数量:

磁盘被分割成若干个物理块,位示图中的每一位(bit)用来表示一个物理块的使用情况。因此,首先我们需要根据磁盘的总容量和每个物理块的大小来计算物理块的总数:

在这里插入图片描述

2. 计算位示图的总位数:

由于每一位表示一个物理块,位示图的总位数就等于物理块的总数:

在这里插入图片描述

3. 计算位示图的字节数:

位示图的总位数可以通过除以8(因为1字节 = 8位)来得到位示图的字节数:

在这里插入图片描述

计算实例:

参数设定:

  • 磁盘容量 = 1 TB = 1,024 GB = ( 1,024 \times 1,024 \times 1,024 ) 字节
  • 物理块大小 = 4 KB = ( 4 \times 1,024 ) 字节
  • 字长 = 64 位(虽然字长不影响位示图大小,但在后面讨论优化时会提到)

步骤1:计算物理块数量

根据给定的磁盘容量和每个物理块的大小,我们首先计算物理块的数量:

在这里插入图片描述

步骤2:计算位示图总位数

位示图中的每一位表示一个物理块的使用情况,因此位示图总位数等于物理块的数量:

在这里插入图片描述

步骤3:计算位示图的字节数

现在,我们将位示图的总位数转换为字节数:

在这里插入图片描述

优化讨论:字长的影响

虽然字长不影响位示图的总大小,但它确实影响读取和操作位示图的效率。假设系统的字长是64位,那么我们可以一次读取64位的数据,这比32位系统一次读取32位更快。位示图的优化涉及位操作的效率,比如查询或修改某个位是否为1,通常与系统的字长相关联。

对于64位系统,读取位示图时可以将64位划分为一个“块”处理,这样位示图中的一大段数据可以通过一次操作被访问,而在32位系统中,处理同样的数据可能需要两次操作。因此,字长较大的系统在管理位示图时会更高效。

完整示例:

假设我们要计算位示图的大小,并展示如何进行相关位运算。下面是一个更详细的代码示例,结合上面的理论计算来进行位示图的管理:

#include <stdio.h>int main() {// 定义磁盘容量和块大小unsigned long long disk_capacity = 1024LL * 1024 * 1024 * 1024; // 1 TB 磁盘容量unsigned int block_size = 4 * 1024; // 4 KB 块大小// 计算物理块数量unsigned long long num_blocks = disk_capacity / block_size;// 计算位示图需要的字节数unsigned long long bitmap_size = num_blocks / 8; // 每个字节可以表示8个块printf("磁盘容量: %llu 字节\n", disk_capacity);printf("物理块大小: %u 字节\n", block_size);printf("物理块数量: %llu 个\n", num_blocks);printf("位示图大小: %llu 字节\n", bitmap_size);// 示例位示图初始化和位操作unsigned char bitmap[bitmap_size]; // 位示图数组for (unsigned long long i = 0; i < bitmap_size; i++) {bitmap[i] = 0; // 初始化位示图为0}// 设置第1000个块为已使用unsigned long long block_to_set = 1000;bitmap[block_to_set / 8] |= (1 << (block_to_set % 8));// 检查第1000个块是否已使用if (bitmap[block_to_set / 8] & (1 << (block_to_set % 8))) {printf("第1000个块已使用\n");} else {printf("第1000个块未使用\n");}return 0;
}

结果解释:

  • 磁盘容量:1 TB,表示整个磁盘的总大小。
  • 物理块大小:4 KB,表示每次存储或读取的最小单位。
  • 物理块数量:262,144,000个物理块。
  • 位示图大小:32,768,000字节,用来表示所有这些块的状态。

通过这个过程,我们可以高效地使用位示图来管理磁盘块的分配和回收,同时对系统资源的利用进行优化管理。

综合示例:

假设我们有以下一系列操作:

  1. 第0号块被使用。
  2. 第3号块被使用。
  3. 第5号块被使用。
  4. 查询第3号块是否被使用。
  5. 释放第3号块。
  6. 最后打印出位示图状态。

我们可以通过位运算来逐步实现。

#include <stdio.h>int main() {unsigned char bitmap = 0b00000000; // 位示图初始值,全为0// 设置第0、3、5位bitmap |= (1 << 0); // 设置第0位,bitmap变为0b00000001bitmap |= (1 << 3); // 设置第3位,bitmap变为0b00001001bitmap |= (1 << 5); // 设置第5位,bitmap变为0b00101001// 查询第3位if (bitmap & (1 << 3)) {printf("第3号块被使用\n");} else {printf("第3号块空闲\n");}// 释放第3号块bitmap &= ~(1 << 3); // 清除第3位,bitmap变为0b00100001// 打印位示图状态printf("位示图当前状态: 0b%08b\n", bitmap); // 输出为0b00100001return 0;
}

详细讲解每一步:

  1. 初始状态
    bitmap = 0b00000000。所有位都为0,表示没有资源被使用。

  2. 设置第0号块
    bitmap |= (1 << 0) -> bitmap = 0b00000001,第0位变为1,表示第0号块被使用。

  3. 设置第3号块
    bitmap |= (1 << 3) -> bitmap = 0b00001001,第3位变为1,表示第3号块也被使用。

  4. 设置第5号块
    bitmap |= (1 << 5) -> bitmap = 0b00101001,第5位也变为1,表示第5号块被使用。

  5. 查询第3号块
    bitmap & (1 << 3) -> 结果不为0,表示第3号块确实被使用。

  6. 释放第3号块
    bitmap &= ~(1 << 3) -> bitmap = 0b00100001,第3位被清除为0,表示第3号块被释放。

  7. 最终状态
    输出结果 0b00100001 表示第0和第5号块被使用,其他块空闲。

理论优势与应用场景

位示图的主要优势在于:

  • 高效的空间利用:每一位只需要1 bit,比起使用整型数组更节省空间。
  • 快速查询:通过简单的位运算即可实现状态的高效查询与修改。

位示图在文件系统、内存管理、并行处理中的任务分配等场景中非常常用,尤其是在资源状态需要频繁查询、设置、清除的情况下。

练题

我们来计算计算机系统的字长为64位、磁盘容量为512GB、物理块大小为4MB时的位示图大小。

已知参数:

  1. 磁盘容量 = 512GB = ( 512 \times 1024 \times 1024 \times 1024 ) 字节
  2. 物理块大小 = 4MB = ( 4 \times 1024 \times 1024 ) 字节
  3. 字长 = 64位(计算位示图大小时,字长并不影响位示图总大小,它影响的是读取的效率)

计算过程:

1. 计算磁盘的物理块数量

首先我们需要计算磁盘上总共有多少个物理块:

在这里插入图片描述

将具体的值代入公式:

在这里插入图片描述

2. 计算位示图总位数

因为每一位表示一个物理块是否已被使用,所以位示图的总位数等于物理块的数量:

在这里插入图片描述

3. 计算位示图的字节数

位示图的总位数转化为字节数,我们知道1字节等于8位,因此:

在这里插入图片描述

4. 计算位示图的字数

我们要根据64位字长计算位示图的大小,以字为单位。由于1个字等于64位(即8字节),因此:

在这里插入图片描述

将计算出的字节数代入公式:

在这里插入图片描述

结论:

在字长为64位、磁盘容量为512GB、物理块大小为4MB的情况下,位示图的大小为2,048字

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/433996.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot文档管理系统:架构与功能

第2章相关技术 2.1 Java技术介绍 Java语言擅长开发互联网类应用和企业级应用&#xff0c;现在已经相当的成熟&#xff0c;而且也是目前使用最多的编程语言之一。Java语言具有很好的面向对象性&#xff0c;可以符合人的思维模式进行设计&#xff0c;封装是将对象的属性和方法尽可…

Ansible流程控制-条件_循环_错误处理_包含导入_块异常处理

文章目录 Ansible流程控制介绍1. 条件判断2. 循环3. 循环控制4. 错误处理5. 包含和导入6. 块和异常处理7. 角色的流程控制*include_tasks、import_tasks_include之间的区别 条件语句再细说且、或、非、是模糊条件when指令的详细使用方法 循环语句再细说如何使用使用item变量结合…

SpringBoot集成Redis及SpringCache缓存管理

1.集成Redis 1.导入依赖 <!--spirngboot springdata对redis支持--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2.配置信息 #数据源配置…

08-Registry搭建docker私仓

08-Registry搭建docker私仓 Docker Registry Docker Registry是官方提供的工具&#xff0c;用于构建私有镜像仓库。 环境搭建 Docker Registry也是Docker Hub提供的一个镜像&#xff0c;可以直接拉取运行。 步骤&#xff1a; 拉取镜像 docker pull registry启动Docker R…

Doris安装部署指南

Doris安装部署指南 一、环境准备二、下载并解压安装包三、配置FE和BEFE配置BE配置四、验证集群状态五、集群扩容与缩容六、总结Apache Doris(原百度Palo)是一款基于MPP架构的高性能、实时的分析型数据库。它支持标准SQL,高度兼容MySQL协议,能够运行在绝大多数主流的商用服务…

1.1.5 计算机网络的性能指标(下)

时延&#xff1a; 指数据从网络的一端传送到另一端所需的时间。有时候也称为延迟或迟延。 总时延发送时延传播时延处理时延排队时延 发送时延&#xff1a; 又名传输时延&#xff0c;节点将数据推向信道所花的时间 数据长度/发送速率 传播时延&#xff1a; 电磁波在信道…

20.指针相关知识点1

指针相关知识点1 1.定义一个指针变量指向数组2.指针偏移遍历数组3.指针偏移的补充4.指针和数组名的见怪不怪5.函数、指针、数组的结合 1.定义一个指针变量指向数组 指向数组首元素的地址 指向数组起始位置&#xff1a;等于数组名 #include <stdio.h>int main(){int ar…

56 门控循环单元(GRU)_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录门控循环单元&#xff08;GRU&#xff09;门控隐状态重置门和更新门候选隐状态隐状态 从零开始实现初始化模型参数定义模型训练与预测 简洁实现小结练习 门控循环单元&#xff08;GRU&#xff09; 之前我们讨论了如何在循环神经网络中计算梯…

爬取元气手机壁纸简单案例(仅用于教学,禁止任何非法获利)

爬虫常用的库 爬虫&#xff08;Web Scraping&#xff09;是一种从网页上提取数据的技术。在 Python 中&#xff0c;有许多库可以帮助实现这一目标。以下是一些常用的爬虫库&#xff0c;以及对 BeautifulSoup 的详细介绍。 常用爬虫库 1.Requests ​ a.功能&#xff1a;用于发…

Mysql优化(常见优化)

插入数据 批量插入&#xff1a;因为一条条插入时&#xff0c;每一条数据的插入都要与数据库建立连接&#xff0c;并且关闭连接 手动提交事物&#xff1a; 主键顺序插入 大批量数据插入 如果一次性需要插入大批量数据&#xff0c;使用insert语句插入性能较低&#xff0c;此时可…

IDEA相关设置总结

目录 1.设置JDK 2.设置忽略大小写检查 3.设置字体大小 4.设置类的信息 5.包名分级 1.设置JDK 2.设置忽略大小写检查 3.设置字体大小 4.设置类的信息 5.包名分级 取消勾选

Mybatis(进阶部分)

四 Mybatis完成CURD&#xff08;二&#xff09; 4.5 多条件CRUD 之前的案例中&#xff0c;接口里方法的形参个数都是1个&#xff1b;如果方法形参是两个或者两个以上时&#xff0c;MyBatis又该如何获取获取参数呢&#xff1f; Mybatis提供了好几种方式&#xff0c;可以获取多…

erlang学习:Linux命令学习7

grep进阶&#xff0c;正则表达式初步学习 正则表达式简介 正则表达式是由一些具有特殊含义的字符组成的字符串&#xff0c;多用于查找、替换符合规则的字符串。在表单验证、Url映射等处都会经常用到,同样在linux中也能够用到。 元字符 元字符&#xff1a;即为有特定含义的字…

搭建基于H.265编码的RTSP推流云服务器

一、前言 网上能够找到的RTSP流地址&#xff0c;均是基于H.264编码的RTSP流地址&#xff0c;无法测试应用是否可以播放H265实时流为此&#xff0c;搭建本地的把H.264转码成H.265的RTSP服务器&#xff0c;不管是通过VLC搭建本地RTSP服务器&#xff0c;还是通过FFmpeg搭建本地RT…

自定义knife4j访问路径

文章目录 本文档只是为了留档方便以后工作运维&#xff0c;或者给同事分享文档内容比较简陋命令也不是特别全&#xff0c;不适合小白观看&#xff0c;如有不懂可以私信&#xff0c;上班期间都是在得 原由&#xff0c;嫌弃doc.html 太大众 直接重定向&#xff0c;直接上代码了 p…

数据结构:详解搜索二叉树

目录 一、搜索二叉树的概念 二、搜索二叉树的基本结构 三、搜索二叉树的插入 四、搜索二叉树的查找 五 、搜索二叉树的删除 一、搜索二叉树的概念 ⼆叉搜索树⼜称⼆叉排序树&#xff0c;它或者是⼀棵空树&#xff0c;或者是具有以下性质的⼆叉树&#xff1a; 若它的左子树…

smb文件夹共享设置

UOS统信三种不同场景的文件夹共享,分别是:1、UOS系统间的文件共享;2、Windows7系统访问UOS共享的文件;3、UOS系统访问Windows7共享的文件 文章目录 功能概述功能介绍第一种场景:UOS系统之间的文件共享设置步骤一:打开共享文件夹步骤二:共享管理步骤三:设置共享密码步骤…

【步联科技身份证】 身份证读取与解析———未来之窗行业应用跨平台架构

一、身份证解析代码 C# function 身份证数据解析_湖南步联科技(wzxx) {var result {};result[xm] wzxx.substr(0, 15);result[xbdm] wzxx.substr(15, 1);result[mzdm] wzxx.substr(16, 2);result[csrq] wzxx.substr(18, 8);result[dzmc] wzxx.substr(26, 35);result[gms…

【射频通信电子线路第六讲】射频信号与调制包括调幅和部分调频的内容

一、调制&#xff08;Modulation&#xff09;与解调&#xff08;Demodulation&#xff09; 1、相关概念 调制是指使一个信号&#xff08;如光信号、高频电磁振荡等&#xff09;的某些参数&#xff08;振幅、频率和相位&#xff09;按照另一个欲传输的信号的特点变化的过程。 …

普通二叉搜索树的模拟实现【C++】

二叉搜素树简单介绍 二叉搜索树又称二叉排序树&#xff0c;是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 注意…