第十七天:原码、反码、补码与位运算

原码、反码、补码与位运算

一、原码、反码、补码

1、原码

  • 定义:原码是一种简单的机器数表示法。对于一个有符号整数,最高位为符号位, 0 表示正数, 1 表示负数,其余位表示数值的绝对值。
  • 示例:以 8 位二进制为例, +5 的原码是 00000101 , -5 的原码是 10000101 。
  • 问题:原码在进行加减法运算时比较复杂,因为要根据符号位判断是加法还是减法,并且对于 0 有两种表示形式( +0 : 00000000 , -0 : 10000000 ),这给计算机处理带来不便。

2、反码

  • 定义:正数的反码与原码相同;负数的反码是在原码的基础上,符号位不变,其余各位取反。
  • 示例:还是以 8 位二进制为例, +5 的反码是 00000101 , -5 的原码是 10000101 ,其反码则为 11111010 。
  • 作用:反码主要是作为从原码到补码的过渡。虽然它解决了 0 的表示不唯一问题( +0 和 -0 的反码都是 00000000 ),但在加减法运算上仍不够理想。

3、补码

  • 定义:正数的补码与原码相同;负数的补码是在反码的基础上,末位加 1 。

  • 示例:同样 8 位二进制, +5 的补码是 00000101 , -5 的反码是 11111010 ,其补码则为 11111011 。

  • 优势:补码在计算机中得到广泛应用,它解决了原码和反码在运算上的不足。在补码系统中, 0 只有一种表示形式( 00000000 )。而且使用补码进行加减法运算时,不需要额外判断符号位,可以直接将符号位和数值位一起参与运算,简化了运算规则,提高了运算效率。例如,计算 5 + (-3) , 5 的补码是 00000101 , -3 的补码是 11111101 ,两者相加:

    00000101

  • 11111101

100000010

由于是 8 位二进制,最高位的 1 溢出被舍弃,结果为 00000010 ,即 2 ,运算结果正确。

  • 原码是最直观的有符号数表示方法,但运算复杂且 0 的表示不唯一。
  • 反码是从原码到补码的过渡,一定程度上解决了 0 的表示问题,但运算仍不够简便。
  • 补码克服了原码和反码的缺点,成为计算机中表示有符号整数的标准方式,极大地简化了运算逻辑,提高了计算机处理有符号整数运算的效率。

二、位运算

1. 位与( & )

  • 运算规则:对两个整数的二进制表示中每一位进行比较,只有当两个对应位都为 1 时,结果位才为 1 ,否则为 0 。
  • 示例代码:
 
#include <iostream>int main() {int num1 = 10; // 二进制: 1010int num2 = 6;  // 二进制: 0110int result = num1 & num2;std::cout << num1 << " & " << num2 << " = " << result << std::endl;// 计算过程://  1010// & 0110// ------//  0010  结果为2return 0;
}
  • 应用场景:
  • 掩码操作:通过与一个特定的掩码值进行位与操作,可以提取或保留某些位。例如,要获取一个字节(8位)的低4位,可以与掩码 0x0F (二进制 00001111 )进行位与操作。
  • 判断奇偶性:与 1 进行位与操作,如果结果为 1 ,则该数为奇数;如果结果为 0 ,则为偶数。因为奇数的二进制最低位是 1 ,偶数的二进制最低位是 0 。

2. 位或( | )

  • 运算规则:对两个整数的二进制表示中每一位进行比较,只要两个对应位中有一个为 1 ,结果位就为 1 ,只有当两个对应位都为 0 时,结果位才为 0 。
  • 示例代码:
#include <iostream>int main() {int num1 = 10; // 二进制: 1010int num2 = 6;  // 二进制: 0110int result = num1 | num2;std::cout << num1 << " | " << num2 << " = " << result << std::endl;// 计算过程://  1010// | 0110// ------//  1110  结果为14return 0;
}

应用场景:

  • 设置标志位:如果要将一个整数的某些位设置为 1 ,可以与一个相应位为 1 的掩码进行位或操作。例如,要将一个整数的第3位和第5位设置为 1 ,可以与掩码 0x28 (二进制 00101000 )进行位或操作。
  • 合并数据:在处理一些标志集合时,可以通过位或操作将不同的标志合并到一个整数中。

3. 异或( ^ )

  • 运算规则:对两个整数的二进制表示中每一位进行比较,当两个对应位不同时,结果位为 1 ,当两个对应位相同时,结果位为 0 。
  • 示例代码:
#include <iostream>int main() {int num1 = 10; // 二进制: 1010int num2 = 6;  // 二进制: 0110int result = num1 ^ num2;std::cout << num1 << " ^ " << num2 << " = " << result << std::endl;// 计算过程://  1010// ^ 0110// ------//  1100  结果为12return 0;
}

应用场景:

  • 数据加密与解密:简单的异或加密算法中,通过将数据与一个密钥进行异或操作来加密数据,解密时再次与相同的密钥异或即可还原数据。
  • 交换两个数:不使用临时变量交换两个整数的值。例如:
#include <iostream>int main() {int a = 5;int b = 7;a = a ^ b;b = a ^ b;a = a ^ b;std::cout << "a = " << a << ", b = " << b << std::endl;return 0;
}
  • 利用了异或操作的特性, a ^ b ^ b 等于 a , a ^ b ^ a 等于 b ,从而实现了两个数的交换。

4. 按位取反( ~ )

  • 运算规则:对一个整数的二进制表示中的每一位进行取反操作,即将 0 变为 1 , 1 变为 0 。
  • 示例代码:
#include <iostream>int main() {int num = 5; // 二进制: 0000 0101int result = ~num;std::cout << "~" << num << " = " << result << std::endl; // 计算过程:// 原: 0000 0101// 取反: 1111 1010 // 在有符号整数中,这是 -6 的补码表示return 0;
}

应用场景:

  • 创建掩码:通过对特定值进行按位取反可以生成用于位操作的掩码。例如,要创建一个除了第 3 位为 0 其余位都为 1 的掩码,可以对 1 << 3 (即 0000 1000 )进行按位取反,得到 1111 0111 。
  • 在特定算法中反转位模式:某些加密算法或数据处理算法中可能需要对数据的位模式进行反转。

5. 左移( << )

  • 运算规则:将一个整数的二进制表示向左移动指定的位数,右边空出的位用 0 填充。每左移一位,相当于该数乘以 2 (在不溢出的情况下)。
  • 示例代码:
#include <iostream>int main() {int num = 5; // 二进制: 0000 0101int result = num << 2;std::cout << num << " << 2 = " << result << std::endl; // 计算过程:// 原: 0000 0101// 左移2位: 0001 0100  结果为20return 0;
}

应用场景:

  • 快速乘法:当需要将一个数乘以 2 的幂次方时,使用左移操作比乘法操作更高效。例如, a * 8 可以写成 a << 3 ,因为 8 = 2^3 。
  • 设置标志位:通过左移操作可以将 1 移动到特定位置来设置标志位。例如, 1 << 5 得到 0010 0000 ,可用于设置第 5 位的标志。

6. 右移( >> )

  • 运算规则:将一个整数的二进制表示向右移动指定的位数。对于无符号整数,左边空出的位用 0 填充;对于有符号整数,如果原数为正数,左边空出的位用 0 填充,如果原数为负数,左边空出的位用符号位(即最高位)填充,这称为算术右移。每右移一位,相当于该数除以 2 (向下取整)。
  • 示例代码(无符号整数):
#include <iostream>int main() {unsigned int num = 20; // 二进制: 0001 0100unsigned int result = num >> 2;std::cout << num << " >> 2 = " << result << std::endl; // 计算过程:// 原: 0001 0100// 右移2位: 0000 0101  结果为5return 0;
}
  • 示例代码(有符号整数):
#include <iostream>int main() {int num = -20; // 二进制补码: 1110 1100int result = num >> 2;std::cout << num << " >> 2 = " << result << std::endl; // 计算过程:// 原: 1110 1100// 右移2位: 1111 1011  结果为 -5return 0;
}

应用场景:

  • 快速除法:当需要将一个数除以 2 的幂次方时,使用右移操作比除法操作更高效。例如, a / 4 可以写成 a >> 2 ,因为 4 = 2^2 。
  • 提取特定部分:可以通过右移操作将需要的位移动到最低位,然后通过与操作提取。例如,要获取一个整数二进制表示的低 4 位,可以先右移 n 位( n 为需要丢弃的高位数),然后与 0x0F 进行与操作。

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

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

相关文章

一次完整的 Docker 启动失败排错之旅:从 `start-limit` 到 `network not found

一次完整的 Docker 启动失败排错之旅&#xff1a;从 start-limit 到 network not found 你是否也曾自信地敲下 sudo systemctl start docker&#xff0c;却只得到一个冰冷的 failed&#xff1f;这是一个开发者和运维工程师都可能遇到的场景。本文将通过一个真实的排错案例&…

Tdengine 时序库年月日小时分组汇总问题

年月分组select to_char(collection_time ,"yyyy-mm") AS date, cast(SUM(a.stage_value)as DOUBLE) as stage_value from TABLE GROUP BY date年月日分组select to_char(collection_time ,"yyyy-mm-dd") AS date, SUM(a.stage_value)as DOUBLE) as stage_…

数据结构(01)—— 数据结构的基本概念

408前置学习C语言基础也可以看如下专栏&#xff1a;打怪升级之路——C语言之路_ankleless的博客-CSDN博客 目录 1. 基本概念 1.1 数据 1.2 数据元素 1.3 数据项 1.4 组合项 1.5 数据对象 1.6 数据类型 2. 数据结构 2.1 逻辑结构 2.2 存储结构 2.3 数据的运算 在学…

什么是模型并行?

模型并行c 简单来说&#xff0c;就是把一个模型拆开来放到多个 GPU 上&#xff0c;一起训练&#xff0c;从而化解“显存塞不下模型”的问题!更多专业课程内容可以听取工信部电子标准院《人工智能大模型应用工程师》课程获得详解&#xff01;

跑yolov5的train.py时,ImportError: Failed to initialize: Bad git executable.

遇到的问题&#xff1a; Traceback (most recent call last):File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 296, in <module>refresh()File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 287…

TCP如何实现可靠传输?实现细节?

TCP如何实现可靠传输&#xff1f;实现细节&#xff1f;如何实现可靠传输&#xff1f;拥塞控制的主要机制TCP流量控制怎么实现的&#xff1f;如何实现可靠传输&#xff1f; TCP通过自身的序列号、确认应答、数据效验、超时重传、流量控制、拥塞避免&#xff0c;确保了数据传输的…

Linux 服务器性能监控、分析与优化全指南

Linux 服务器性能监控、分析与优化在现代 IT 架构中&#xff0c;Linux 服务器作为承载业务系统的核心载体&#xff0c;其性能表现直接决定了服务的稳定性、响应速度与用户体验。无论是高并发的 Web 服务、数据密集型的数据库集群&#xff0c;还是承载虚拟化平台的宿主机&#x…

基于wenet和模型做企业直播敏感语音屏蔽技术

本文介绍了基于Wenet语音识别工具包的实时敏感词屏蔽技术方案。该方案通过客户端缓存25秒直播内容&#xff0c;利用Wenet的流式识别和断句检测功能&#xff0c;实时检测讲师语音中的敏感词&#xff0c;并将对应位置的语音替换为"哔"声。文章详细阐述了Wenet的两种识别…

42.MySQL视图

1.一个需求emp 表的列信息很多&#xff0c;有些信息是个人重要信息 (比如 sal, comm, mgr, hiredate)&#xff0c;如果我们希望某个用户只能查询 emp 表的 (empno、ename, job 和 deptno ) 信息&#xff0c;有什么办法&#xff1f;表的数据&#xff1a;想让用户查询到的&#x…

MinIO01-入门

零、文章目录 MinIO01-入门 1、介绍 &#xff08;1&#xff09;介绍 MinIO 是一款基于 Apache License v2.0 的开源对象存储系统&#xff0c;专为海量非结构化数据&#xff08;如图片、视频、日志文件等&#xff09;设计&#xff0c;兼容 Amazon S3 API&#xff0c;支持高性…

*Docker数据卷(Volume)核心机制剖析:持久化与共享的终极解决方案

根本问题当容器被删除时&#xff0c;其内部产生的所有文件&#xff08;包括配置文件、数据库、日志&#xff09;都会不可逆丢失。数据卷&#xff08;Volume&#xff09;通过外置存储方案彻底解决此痛点。一、数据卷与普通容器存储对比实验 场景1&#xff1a;无卷模式下的写入悲…

原型模式在C++中的实现与面向对象设计原则

引言 在软件开发中&#xff0c;原型模式是一种常用的设计模式&#xff0c;主要用于创建对象的克隆。通过原型模式&#xff0c;我们可以避免复杂的对象创建过程&#xff0c;尤其是当对象的初始化需要大量资源或复杂操作时。本文将通过一个具体的例子&#xff0c;详细介绍如何在C…

SpringCloud学习------Gateway详解

在微服务架构中&#xff0c;随着服务数量的激增&#xff0c;如何统一管理服务入口、实现请求路由、保障服务安全等问题日益突出。SpringCloud Gateway 作为 Spring 官方推出的网关组件&#xff0c;凭借其强大的功Gateway 是 Spring 官方基于 Spring、SpringBoot 和 Project Rea…

计算机网络:子网掩码在路由转发中的关键作用

在路由表中,子网掩码是一个不可或缺的组成部分,其核心作用是精确界定IP地址中“网络位”和“主机位”的边界,从而实现路由器对数据包的准确转发。以下从多个角度详细解释其必要性: 1. 区分网络位与主机位,定位目标网络 IP地址由“网络标识”(网络位)和“主机标识”(主…

14.Home-新鲜好物和人气推荐实现

新鲜好物实现1.准备模板<script setup>import HomePanel from ./HomePanel.vue</script><template><homePanel></HomePanel><!-- 下面是插槽主体内容模版<ul class"goods-list"><li v-for"item in newList" :ke…

Linux 系统重置用户密码指南

Linux 系统重置用户密码指南 在 Linux 系统运维中&#xff0c;重置用户密码&#xff08;尤其是 root 密码&#xff09;是一项核心技能。当您忘记密码时&#xff0c;可以通过进入单用户模式或恢复模式来修改密码。此方法适用于大多数 Linux 发行版&#xff0c;如 RHEL/CentOS、D…

[自动化Adapt] GUI交互(窗口/元素) | 系统配置 | 非侵入式定制化

第三章&#xff1a;GUI交互&#xff08;窗口/元素&#xff09; 各位OpenAdapt探索者&#xff0c;欢迎回来~ 在第一章&#xff1a;录制引擎中&#xff0c;我们揭示了OpenAdapt如何通过"眼睛和耳朵"捕捉所有操作细节。接着在第二章&#xff1a;数据模型中&#xff0c…

Java 模版进阶

文章目录模版通配符模版 通配符 实例 import java.util.ArrayList; import java.util.List;class Message<T> {private T message ;public T getMessage() {return message;}public void setMessage(T message) {this.message message;} } public class test {public …

统计鱼儿分布情况 Java

假设有一个池塘&#xff0c;管理员在池塘中添加随机数量的鱼类&#xff0c;为了统计鱼类的分布情况&#xff0c;他将池塘划分为8*8的二维网格&#xff0c;鱼儿随机游动&#xff0c;但是每个网格中最多容纳100条鱼&#xff0c;要求编写程序显示鱼儿分布情况&#xff0c;并计算鱼…

【HUST】计算机|大学计算机基础内容(纯科普向)+数据结构数组、树、队列【旧文搬运】

最初发布时间&#xff1a;2020-09-19 23:17:48 以前写这篇文章&#xff0c;主要是接触到一些非计算机学院的同学&#xff0c;为了交流方便我写下了这篇文章……虽然现在回过头来看写得也比较草率&#xff0c;但确实是我对电脑的基础操作的最早的认识&#xff0c;放到现在我绝对…