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

重学Android:从位运算到二进制表示(零)

前言

以下内容针对非科班同学,可以快速掌握位运算和二进制表示等计算机基础运算知识,看过源码的同学都知道,源码中大量运用了位运算知识,如果你对这方面不了解的话,看起来是比较困难的,如果你工作接触到蓝牙数据,串口数据收发等内容,这方面更是你必须了解的。

首先说下我自己,以前非科班出身,这方面内容几乎没了解过,但从实习开始领导直接告诉我让我负责蓝牙(用485通信的运动数据蓝牙模块)传输这方面工作(回头想想工作这几年一共接触到了不下于8种不同的蓝牙模块协议),就开始疯狂恶补这方面内容16进制,位运算,异或校验,校验和,进制转换…,越看越蒙,发现短期内并不能完全理解,于是就边学边开发,不知不觉就突然懂了,就是这么神奇,所以说如果前期看不懂没关系,看到能认识就行,再翻翻笔记理解一下,慢慢就懂了(经验之谈)!

说的有点多,直接开搂!

1. 二进制表达形式


1.1 什么是二进制?

计算机内部是通过二进制(0和1)来存储和处理数据的。每一位(bit)只能取两个值,0或1,而多个二进制位(bit)组合起来可以表示不同的数值。比如,8个二进制位可以表示的数值范围是0000000011111111,即0到255,也代表一个字节。

1.1 高位低位?

我们或许在某些地方听说过,高几位和低几位之说,它们都是对于二进制而言诞生的,比如一个字节 8个bit 00010010 通常把左边的称为高位,右边的称为低位,可以叫高四位0001和低四位0010,这没什么讲的,大家了解就行。

2. 位运算概述


位运算是直接对二进制位进行操作的运算方式,常用于底层开发、性能优化和算法实现中。与普通的算数运算(加法、减法等)不同,位运算操作的是二进制位,速度极快,且适用于很多底层系统和嵌入式开发。常见的位运算包括:位与(&)、位或(|)、位异或(^)、位取非(~)、左移(<<)、右移(>>)以及无符号右移(>>>)。

2.1 位与(&)

位与(&)是一个二元运算符,它对比特位上的两个数字进行操作。当且仅当两个相应的位都是1时,结果才为1,否则为0。

举个栗子:

  1101 (13)  
& 1011 (11)  
----------
  1001 (9)

只有第二位和第四位都为1,所以结果是1001,即9。通常使用(&)提取相应位的值,比如获取一个字节的高4位 就 &0xF0,获取低四位就 &0x0F

2.2 位或(|)

位或(|)也是一个二元运算符,它会将两个数字的对应位进行比较,只要其中一个位为1,结果就是1。

举个栗子:

  1101 (13)  
| 1011 (11)  
----------
  1111 (15)

只有第二位和第四位都为0时才是0,其它位只要有一个为1,结果就为1。所以结果是1111,即15。这个通常运用是将高位和低位相加得到一个值,比如一个值使用高四位存储数值另一个用低四位存储,那么使用(|)就能等到他俩的累加和。

2.3 位异或(^)

位异或(^)是一个二元运算符,两个位相同则结果为0,不同则结果为1。

举个栗子:

  1101 (13)  
^ 1011 (11)  
----------
  0110 (6)

这个的应用一般是计算数据帧的校验(异或校验),确保帧完整。

2.4 位取非(~)

位取非(~)是一个一元运算符,它对每一位进行反转操作,将0变成1,将1变成0。

举个栗子:

  ~1101 (13)
  ---------
   0010 (-14)  (假设使用4位表示,反转操作会影响符号位)

位取非对一个数的二进制表示进行反转。在计算机中,取非的结果通常会被解释为负数,因为它的符号位(最高位)发生了变化。

2.5 左移(<<)

左移运算符(<<)是将数字的二进制表示向左移动若干位,左移相当于将数值乘以2的幂。左移时,低位补0。

举个栗子:

  00000001 (1)  
<< 2   
-----------
  00000100 (4)

1左移两位后变成了4。每左移一位,相当于将数字乘以2。位运算由于是直接操作位,所以运算极快,现在知道为啥源码中这么常见了吧。

2.6 右移(>>)

右移运算符(>>)是将数字的二进制表示向右移动若干位,右移相当于将数值除以2的幂。右移时,符号位会根据符号来进行扩展。

举个栗子:

  11100101 (-27)  
>> 3  
-----------
  11111100 (-4)

-27右移3位后变成了-4。右移时,高位补充符号位(在负数情况下为1)。这时候肯定会有人疑惑包括我在内,就算保留符号位,右移三位也是10001100啊,为什么是11111100,这里就简单记住负数移位后的空缺位将用1填充,正数是0填充,这是因为负数一般用补码表示,马上会介绍。

这里只是个特殊的栗子讲解下,开发中最常用的是正数的右移,对于负数我几乎没碰到过。

2.7 无符号右移(>>>)

无符号右移(>>>)与带符号的右移不同,它不保留符号位,而是补充0到高位。

举个栗子:

  11100101 (-27)  
>>> 3   
-----------
  00011100 (28)

-27无符号右移3位后变成了28,因为无符号右移会用0补充符号位。

小结

运算符符号描述示例结果解释
位与&如果对应位都是1,则结果为1;否则为0。1101 & 10111001(13 & 11 = 9)
位或如果对应位中至少有一个1,则结果为1;否则为0。1101 丨10111111(13 | 11 = 15)
位异或^如果对应位不同,则结果为1;如果相同,则为0。1101 ^ 10110110(13 ^ 11 = 6)
位取非~对二进制表示的每一位数字进行取反。~11010010(假设操作在4位上,~13 = 2)
左移<<将二进制位左移指定的位数,低位补0。0011 << 21100(3 << 2 = 12)
右移>>将二进制位右移指定的位数,高位根据符号位填充。1110 >> 11111(-2 >> 1 = -1,假设操作在4位上)
无符号右移>>>将二进制位右移指定的位数,高位补0。11100101 >>> 300011100(-27 >>> 3 = 536870902,假设32位)

3. 原码、反码与补码


在计算机中,负数是通过原码、反码和补码来表示的。这些方法影响着数值的存储方式及运算效率。了解这些概念是理解计算机如何处理负数的关键。

3.1 原码

原码是最简单的表示方法。它的最高位是符号位,0表示正数,1表示负数。其余位表示数字的大小。

举个栗子:

  • +7的原码:00000111
  • -7的原码:10000111

原码的优点是简单易懂,缺点是对于运算来说比较复杂,不方便进行加减运算,特别是当正负数混合时更为麻烦。

3.2 反码

反码同样最高位是符号位,0代表正数,1代表负数。其余位表示数值,与原码不同的是,负数的表示方法不同。负数的反码表示方法:将它的绝对值按位取反

举个栗子:

  • +7的反码:00000111
  • -7的反码:11111000

反码的优点是对于加减运算来说比原码简单,特别是当正负数混合时更简单,但缺点是在进行乘除运算时会出现问题。

3.3 补码

补码是现代计算机最常用的负数表示方法。补码同样最高位是符号位,0代表正数,1代表负数。其余位表示数值,其表示方法不同于原码和反码。补码解决了反码的不足,使得加减法运算变得更加简单高效。负数的补码表示方法:将其绝对值的二进制表示取反,然后加上1

举个栗子:

  • +7的补码:00000111
  • -7的补码:11111001

补码不仅能简化加减法运算,还能避免符号位带来的问题。

小结

类型描述正数示例负数示例特点
原码最高位为符号位,0表示正,1表示负,其余位表示数值。+7: 0000 0111-7: 1000 0111简单,但正负数加减法操作复杂
反码正数的反码与原码相同,负数的反码为其原码除符号位外各位取反。+7: 0000 0111-7: 1111 1000解决了0的表示问题,简化了加减法
补码正数的补码与原码相同,负数的补码为其反码加1。+7: 0000 0111-7: 1111 1001计算机内部普遍使用,优化了运算效率

4. 最后


希望对你有帮助,一起努力,共同进步!

另外给喜欢记笔记的同学安利一款好用的云笔记软件,对比大部分国内的这个算还不错的,免费好用::wolai

_

http://www.kler.cn/a/381273.html

相关文章:

  • 【算法】【优选算法】双指针(下)
  • Git 测验
  • C++11新特性之Lambda函数
  • 精密机械代加工服务,为你的企业加速发展!
  • Centos部署资料
  • 基于MATLAB的战术手势识别
  • QT pro项目工程的条件编译
  • vue--vueCLI
  • 企业CRM管理系统PHP源码/PHP客户关系CRM客户管理系统源码
  • 【Python】计算机视觉应用:OpenCV库图像处理入门
  • Python Pandas内存管理技巧助力高效处理大数据
  • 针对告警数量、告警位置、告警类型等参数进行统计,并做可视化处理的智慧能源开源了
  • 微服务架构面试内容整理-Ribbon
  • 通过Flink读写云原生数据仓库AnalyticDB PostgreSQL版(ADB PG)数据
  • LWIP通信协议UDP发送、接收源码解析
  • 使用JdbcTemplate 进行数据库的增、删、改、查
  • ServletContext 对象介绍
  • Redis持久化机制——针对实习面试
  • 力扣11.4
  • 微信小程序 基于协同过滤算法的的校园音乐推荐系统
  • 大客户营销数字销售实战讲师培训讲师唐兴通专家人工智能大模型销售客户开发AI大数据挑战式销售顾问式销售专业销售向高层销售业绩增长创新
  • 低代码解锁跨平台应用开发新境界
  • Elasticsearch核心概念
  • [渲染层网络层错误] net::ERR_CONTENT_LENGTH_MISMATCH 问题解决
  • 【TextIn:开源免费的AI智能文字识别产品(通用文档智能解析识别、OCR识别、文档格式转换、篡改检测、证件识别等)】
  • 利用爬虫爬取网站信息