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

通过位运算,实现单字段标识多个状态位

可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课.

这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加.

考虑只用一个状态标志位,利用位运算,来标识多门课的通过或否.

这与Linux的文件权限思路一致

Linux文件和目录的权限




设计及实现


  • 左移(<<):

  • 右移(>>):

  • |(或运算):只要当一方为 true 时,结果就是 true,否则为 false。 (有1就为1,全0才为0)

  • &(与运算):只有当两方都为 true 时,结果才是 true,否则为 false。(全1才为1,有0就为0)


对于正数和负数,左移一位就相当于乘以2的1次方,左移n位就相当于乘以2的n次方

如xxxxxx<<2即左移2位,右边空出的位用0填补,高位左移溢出则舍弃该高位


步骤一:


如语文成绩率先出来,我们约定,以这个字段(记为attr)的第一位,来代表该学生语文有没有通过测评(0否1是)


attr为当前该属性字段的值(从数据库里取出来的值). index为约定的第几位来标识当前业务,index从0开始计数


package main

import "fmt"

func main() {

 // 记录阶段
    //如果语文成绩测评通过,调一个写接口,初始attr值为0,约定的表示位置为第1位,又因为从0开始计数,故而index=0

 setRs := set(00//将attr字段的最新值,记录进数据库的attr字段



 // 查询阶段
 //当需要获知该学生的语文是否通过时. 查数据库,获取上面记录进的值(此时setRs即attr=1); 进而get方法,可知道是否通过(如果rs结果为1,则通过)
 rs := get(setRs, 0)
 _ = rs
}

func set(attr, index int) int {
 tmp := 1 << index
    // 1左移0位,即原地没动,还是1
 fmt.Printf("1 << index %d 值为%d:\n", index, tmp)
    // 1 | 0,或运算,有1就为1,故而setRs=1
 setRs := tmp | attr
 fmt.Println(setRs)
 
 return setRs
}

func get(attr, index int) int {
 tmp := attr >> index
    // 1右移0位,即原地不动,还是1
 fmt.Printf("attr %d >> index %d 值为 %d:\n", attr, index, tmp)
 // 0001 & 0001,与运算,全1才为1,故而为0001,即为十进制数1
 getRs := tmp & 1
 fmt.Println(getRs)

 return getRs
}



输出为:

1 << index 0 值为1:
1
attr 1 >> index 0 值为 1:
1

alt

假设孙山语文及格, 张继语文落榜(则不调用写接口,只有通过才调),则二人当前attr的值为1和0.

这样就完成了语文科目的处理




步骤二:


几天后数学测评结果也出来了,继续用attr,约定以这个字段的第二位,来代表该学生数学有没有通过测评(0否1是)


同样用之前的代码,

记录阶段:

package main

import "fmt"

func main() {

 // 记录阶段
    //如果数学成绩测评通过,调写接口,约定的表示位置为第1位,又因为从0开始计数,故而index=1
 // 对于孙山,从数据库取出其attr值,为1; 张继的attr值为0

 // 加入二人都通过了数学测评,都需调用如下写接口

 setRsSun := set(11//将attr字段的最新值,记录进数据库的attr字段
 fmt.Println("-----------")
 setRsZhang := set(01)

}

func set(attr, index int) int {
 tmp := 1 << index
    // 1左移1位,即由"0001"变为"0010",即为十进制数2
 fmt.Printf("1 << index %d 值为%d:\n", index, tmp)
    // 对于语文通过带孙山,0010 | 0001,或运算,有1就为1,故而setRs=0011,即十进制数3
 // 对于语文未通过带张继,0010 | 0000,或运算,有1就为1,全0才为0, 故而setRs=0010,即十进制数2
 setRs := tmp | attr
 fmt.Println(setRs)
 
 return setRs
}


1 << index 1 值为2:
3
-----------
1 << index 1 值为2:
2

alt

查询阶段:


package main

import "fmt"

func main() {


 // 查询阶段
 //当需要获知该学生的语文/数学是否通过时. 查数据库,获取其attr的值; 进而get方法,index字段为该科目约定的位置(语文为1,其index为0; 数学为2,其index为1),即可知道是否通过(如果rs结果为1,则通过)
 sunMath := get(setRsSun, 1//setRsSun=3

 fmt.Println("-----------")
 zhangChinese := get(setRsZhang, 0)//setRsZhang=2


 fmt.Println("sunMath is:",sunMath)
 fmt.Println("zhangChinese is:",zhangChinese)
}


func get(attr, index int) int {
 tmp := attr >> index
   
 
 fmt.Printf("attr %d >> index %d 值为 %d:\n", attr, index, tmp)
 
 getRs := tmp & 1
 fmt.Println(getRs)

 return getRs
}



 // 对于孙山,十进制数3即二进制0011,右移1位,即0001,即十进制数1
attr 3 >> index 1 值为 1:
// 0001 & 0001,与运算,全1才为1,故而为1. 即孙山通过了数学
1
-----------
// 对于张继,十进制数2即二进制0010,右移0位,即原地不动,还是0010,十进制数2
attr 2 >> index 0 值为 2:
// 0010 & 0001,全1才为1,否则为0. 即张继没有通过语文
0

sunMath is: 1
zhangChinese is: 0




步骤三:


过了几天,英语结果也出来了.假如孙山没通过,张继通过,爽哥三门都通过,则有

alt

写入和读取过程同上



步骤四:


假如现在第60个科目'信息技术'的测评出炉, 爽哥前面59门课程全部通过,则attr字段的值为 ,

2的n次方对照表

第60门课'信息技术'也高分通过, 则对于最新的attr值,即 1 << index | attr,

1 << 59 | 576460752303423487 = 1152921504606846975,将这个值计入数据库.


如需获取爽哥有无通过第60门课程,1152921504606846975 >> 59 & 1 = 1,即通过


如果将数据库这个attr字段设置为有符号的bigint类型,则最多可标识 60几个不同业务的状态




更通用的代码:


func main(){

 index := uint8("约定的位置" - 1)
 attr := "来自数据库"

}

func SetAttrBit(attr int, index uint8) int {
 return 1 << index | attr
}


func GetAttrBit(attr int, index uint8) int {
 return attr >> index & 1
}


参考:

用位运算来标识状态




番外


alt

"光学电报"

本文由 mdnice 多平台发布

相关文章:

通过位运算,实现单字段标识多个状态位

可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课. 这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加. 考虑只用一个状态标志位,利用位运…...

ALSA pcm接口的概念解释

PCM(数字音频)接口 PCM缩写: Pulse Code Modulation脉冲调制编码,我们理解为通过一定连续时间周期产生数字音频并带有音量样本的处理过程. 模拟信号被记录通过模拟到数字转换器,数字值(也就是某个特定时刻的音量值)获得来自ADC可以进一步处理,接下的图片展示的是个sine wavefor…...

logging的基本使用教程

logging的基本使用教程 一、简介&#xff1a; logging模块是Python的标准库&#xff0c;用于记录应用程序运行时的日志信息。使用logging模块可以帮助您在开发过程中调试代码、追踪问题和监控应用程序的运行状况。 二、使用教程 1、logging模块的基本使用方法&#xff1a; …...

ds套dp——考虑位置转移or值域转移:CF1762F

https://www.luogu.com.cn/problem/CF1762F 分析性质&#xff0c;就是我们选的数要么递增&#xff0c;要么递减&#xff08;非严格&#xff09;然后很明细是ds套dp&#xff0c; f i f_i fi​ 表示以 i i i 开头的答案然后考虑如何转移&#xff08;ds套dp难点反而在转移而不是…...

stm32的GPIO寄存器操作以及GPIO外部中断,串口中断

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&a…...

生成对抗网络入门案例

前言 生成对抗网络&#xff08;Generative Adversarial Networks&#xff0c;简称GANs&#xff09;是一种用于生成新样本的机器学习模型。它由两个主要组件组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;。生成器尝试…...

多头注意力机制

1、什么是多头注意力机制 从多头注意力的结构图中&#xff0c;貌似这个所谓的多个头就是指多组线性变换&#xff0c;但是并不是&#xff0c;只使用了一组线性变换层&#xff0c;即三个变换张量对 Q、K、V 分别进行线性变换&#xff0c;这些变化不会改变原有张量的尺寸&#xf…...

Qt + FFmpeg 搭建 Windows 开发环境

Qt FFmpeg 搭建 Windows 开发环境 Qt FFmpeg 搭建 Windows 开发环境安装 Qt Creator下载 FFmpeg 编译包测试 Qt FFmpeg踩坑解决方法1&#xff1a;换一个 FFmpeg 库解决方法2&#xff1a;把项目改成 64 位 后记 官方博客&#xff1a;https://www.yafeilinux.com/ Qt开源社区…...

[网鼎杯 2020 白虎组]PicDown python反弹shell proc/self目录的信息

[网鼎杯 2020 白虎组]PicDown - 知乎 这里确实完全不会 第一次遇到一个只有文件读取思路的题目 这里也确实说明还是要学学一些其他的东西了 首先打开环境 只存在一个框框 我们通过 目录扫描 抓包 注入 发现没有用 我们测试能不能任意文件读取 ?url../../../../etc/passwd …...

SDL2绘制ffmpeg解析的mp4文件

文章目录 1.FFMPEG利用命令行将mp4转yuv4202.ffmpeg将mp4解析为yuv数据2.1 核心api: 3.SDL2进行yuv绘制到屏幕3.1 核心api 4.完整代码5.效果展示6.SDL2事件响应补充6.1 处理方式-016.2 处理方式-02 本项目采用生产者消费者模型&#xff0c;生产者线程&#xff1a;使用ffmpeg将m…...

决策树C4.5算法的技术深度剖析、实战解读

目录 一、简介决策树&#xff08;Decision Tree&#xff09;例子&#xff1a; 信息熵&#xff08;Information Entropy&#xff09;与信息增益&#xff08;Information Gain&#xff09;例子&#xff1a; 信息增益比&#xff08;Gain Ratio&#xff09;例子&#xff1a; 二、算…...

LLMs Python解释器程序辅助语言模型(PAL)Program-aided language models (PAL)

正如您在本课程早期看到的&#xff0c;LLM执行算术和其他数学运算的能力是有限的。虽然您可以尝试使用链式思维提示来克服这一问题&#xff0c;但它只能帮助您走得更远。即使模型正确地通过了问题的推理&#xff0c;对于较大的数字或复杂的运算&#xff0c;它仍可能在个别数学操…...

【12】c++设计模式——>单例模式练习(任务队列)

属性&#xff1a; &#xff08;1&#xff09;存储任务的容器&#xff0c;这个容器可以选择使用STL中的队列&#xff08;queue) &#xff08;2&#xff09;互斥锁&#xff0c;多线程访问的时候用于保护任务队列中的数据 方法&#xff1a;主要是对任务队列中的任务进行操作 &…...

Python之函数、模块、包库

函数、模块、包库基础概念和作用 A、函数 减少代码重复 将复杂问题代码分解成简单模块 提高代码可读性 复用老代码 """ 函数 """# 定义一个函数 def my_fuvtion():# 函数执行部分print(这是一个函数)# 定义带有参数的函数 def say_hello(n…...

SQL创建与删除索引

索引创建、删除与使用&#xff1a; 1.1 create方式创建索引&#xff1a;CREATE [UNIQUE – 唯一索引 | FULLTEXT – 全文索引 ] INDEX index_name ON table_name – 不指定唯一或全文时默认普通索引 (column1[(length) [DESC|ASC]] [,column2,…]) – 可以对多列建立组合索引 …...

网络协议--链路层

2.1 引言 从图1-4中可以看出&#xff0c;在TCP/IP协议族中&#xff0c;链路层主要有三个目的&#xff1a; &#xff08;1&#xff09;为IP模块发送和接收IP数据报&#xff1b; &#xff08;2&#xff09;为ARP模块发送ARP请求和接收ARP应答&#xff1b; &#xff08;3&#xf…...

HDLbits: Count clock

目前写过最长的verilog代码&#xff0c;用了将近三个小时&#xff0c;编写12h显示的时钟&#xff0c;改来改去&#xff0c;估计只有我自己看得懂&#xff08;吐血&#xff09; module top_module(input clk,input reset,input ena,output pm,output [7:0] hh,output [7:0] mm,…...

【1day】用友移动管理系统任意文件上传漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...

【c++】向webrtc学习容器操作

std::map的key为std::pair 时的查找 std::map<RemoteAndLocalNetworkId, size_t> in_flight_bytes_RTC_GUARDED_BY(&lock_);private:using RemoteAndLocalNetworkId = std::pair<uint16_t, uint16_t...

SpringBoot+Vue3外卖项目构思

SpringBoot的学习&#xff1a; SpringBoot的学习_明里灰的博客-CSDN博客 实现功能 前台 用户注册&#xff0c;邮箱登录&#xff0c;地址管理&#xff0c;历史订单&#xff0c;菜品规格&#xff0c;购物车&#xff0c;下单&#xff0c;菜品浏览&#xff0c;评价&#xff0c;…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...