深入理解原码、反码、补码(结合C语言)

news2025/2/28 5:15:52

一、引出问题

在学习C语言单目操作符中~按位取反的过程中,对这样一段代码的结果产生了疑惑:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main() {
    int a = 0;
    int b = ~a;·//按位取反
    printf("%d\n", b);
    return 0;
}

输出结果:
-1

首先,int整型占4个字节,0化为二进制形式为00000000 00000000 00000000 00000000这样,按位取反后是11111111 11111111 11111111 11111111,化为十进制不应该是一个很大的负数吗,而输出结果却为-1。

之后我查阅资料才发现,我忘记了负数在计算机内存中是以补码的方式存储和进行运算的。于是我又将原码、反码、补码相关的知识复习了一遍,温故而知新,重新总结如下。

二、深入理解原码、反码、补码

在计算机中,数字的二进制位的第一位是符号位,0为正,1为负

首先要明白,原码、反码、补码是计算机用于表示带符号整数的三种编码方式

  1. 原码:原码最高位为符号位,其余位为数值绝对值的二进制值,如5的原码是0000 0101,-5的原码是1000 0110。原码表示最直观,但在进行加减法运算时存在问题,如5+(-5)理论上等于0,但原码相加得1000 1011并不是0000 0000
  2. 反码:正数的反码与原码相同,负数的反码是将原码符号位不变,其余位按位取反。如5的反码即原码0000 0101,-5的反码为1111 1010。
    引入反码是为了更好的解决二进制正数与负数间的加减法问题,如5+(-6)即0000 0101 + 1111 1001 = 1111 1110(反码),转为原码即符号位不变,其余位取反,得1000 0001,正好是-1。
    但反码仍然存在溢出和零的表示问题,如-5+6,即1111 1010 + 0000 0110 => 溢出得0;-5+5即1111 1010 + 0000 0101 = 1111 1111(反码),转为原码即1000 0000,这就与0000 0000的0的原码表示方式存在冲突,一个数总不能有两种表示方法吧。于是就有了下面的补码。
  3. 补码:正数的补码与原码相同,负数的补码是将负数的原码符号位不变,其余位取反后再加1(即负数的反码+1)。如5的补码即原码0000 0101,-5的补码为1111 1011。
    补码的引用很好的解决了加减法和0的表示问题,还能够自然地处理溢出,下面验证一下:
    • -6+5,即1111 1010 + 0000 0101 = 1111 1111,转为原码(补码-1,符号位不变,其余位取反)得1000 0001,即-1,没毛病。
    • -5+6,即1111 1011 + 0000 0110 => 溢出且得0000 0001,正数,即原码本身,得1,没毛病。
    • -5+5,即1111 1011 + 0000 0101 => 溢出且得0000 0000,与0的原码表示相同,没毛病。
      由此可见,在计算机中,补码是最常见和最有效的带符号整数表示方式。
      因此,在计算机中,带符号的整数在内存中存储的是其二进制的补码

那么这就可以理解结果为什么为-1而不是一个很大很大的负数,以上代码的计算过程如下:

//a=0的补码(也是原码)
00000000 00000000 00000000 00000000
//~取反运算得到b的补码
11111111 11111111 11111111 11111111
//补码-1
11111111 11111111 11111111 11111110
//符号位不变,按位取反得到原码
10000000 00000000 00000000 00000001

即得到打印出来的结果为-1

终于,破案了~

三、关于原码、反码、补码之间的转换

1.对于正数,原码 = 反码 = 补码
2.对于负数,此图足以:
请添加图片描述

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

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

相关文章

系列十七、理解SpringBoot中的starter 自定义一个starter

一、概述 作为后端Java程序员&#xff0c;基本上公司的日常开发都是基于SpringBoot进行的&#xff0c;我们使用SpringBoot也是沉醉于它的各种各样的starter带给我们的便利&#xff0c;这些starter为我们带来了众多的自动化配置&#xff0c;通过这些自动化配置&#xff0c;我们可…

为自己创建的游戏编程源码申请软件著作权详细流程(免费分享模板)

以为我这篇文章制作的游戏申请软件著作权为例 Ren‘py 视觉小说 交互式故事游戏制作过程学习笔记(Windows下实现)(多结局游戏)-CSDN博客 一、网站注册 申请软著时&#xff0c;所有的著作权人都需要在中国版权保护中心官网注册账号&#xff0c;并进行实名认证后&#xff0c;才…

使用WalletConnect Web3Modal v3 链接钱包基础教程

我使用的是vueethers 官方文档&#xff1a;WalletConnect 1.安装 yarn add web3modal/ethers ethers 或者 npm install web3modal/ethers ethers2.引用 新建一个js文件&#xff0c;在main.js中引入&#xff0c;初始化配置sdk import {createWeb3Modal,defaultConfig, } from…

【预计IEEE出版|EI征稿通知】第六届下一代数据驱动网络国际学术会议 (NGDN 2024)

第六届下一代数据驱动网络国际学术会议 (NGDN 2024) The Sixth International Conference on Next Generation Data-driven Networks 2024年4月26-28日 | 中国沈阳 基于前几届在英国埃克塞特 (ISPA 2020) 、中国沈阳 (TrustCom 2021) 和中国武汉 (IEEETrustCom-2022) 成功举…

半监督语义分割综述

paper link&#xff1a;https://arxiv.org/pdf/2302.09899.pdf 1. Introduction 图像分割是最古老、研究最广泛的计算机视觉 (CV) 问题之一。图像分割是指将图像划分为不同的非重叠区域&#xff0c;并将相应的标签分配给图像中的每个像素&#xff0c;最终获得ROI区域位置及其类…

【智能家居】二、添加火灾检测模块(烟雾报警功能点)

可燃气体传感器 MQ-2 和 蜂鸣器 代码段 controlDevice.h&#xff08;设备控制&#xff09;smokeAlarm.c&#xff08;烟雾报警器&#xff09;buzzer.c&#xff08;蜂鸣器&#xff09;mainPro.c&#xff08;主函数&#xff09;运行结果 可燃气体传感器 MQ-2 和 蜂鸣器 代码段 …

基于机器深度学习的交通标志目标识别

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 智能交通系统&#xff08;ITS&#xff09;&#xff0c;包括无人驾驶车辆&#xff0c;尽管在道路…

OrangePi 5:ROS2 Humble中使用激光雷达

OrangePi 5&#xff1a;ROS2 Humble中使用激光雷达 文章目录 OrangePi 5&#xff1a;ROS2 Humble中使用激光雷达1、硬件准备2、ROS2 Humble安装2.1 使用集成脚本安装2.2 按ROS2官方指导安装2.3 ROS2安装验证 3、YDLIDAR X2激光雷达驱动安装3.1 YDLIDAR X2激光雷达介绍3.2 YDLID…

go第三方包发布(短精细)

1、清除其他依赖项 $ go mod tidy # 清除不必要的依赖依赖清除完成后&#xff0c;查看go.mod文件配置是否规范 module github.com/fyupeng/rpc-go-netty go 1.19 require ( )2、本地版本创建 $ git tag v0.1.0 # 本地 创建标签3、版本提交 $ git push github v0.1.0 # 推送…

Programming Contest 2023(AtCoder Beginner Contest 331)D题 Tile Pattern --- 题解

目录 D - Tile Pattern 题目大意&#xff1a; 思路&#xff1a; 代码&#xff1a; D - Tile Pattern D - Tile Pattern (atcoder.jp) 题目大意&#xff1a; 给你一个n和q&#xff0c;n为局部棋盘大小(n*n) 并且给出局部棋盘中黑白子位置的放置情况&#xff0c;q为查询次数…

Docker部署Plik临时文件上传系统并且实现远程访问

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik8. 结语 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上…

深入解析JVM内存结构:Metaspace、堆与垃圾收集器

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

Flask使用线程异步执行耗时任务

1 问题说明 1.1 任务简述 在开发Flask应用中一定会遇到执行耗时任务&#xff0c;但是Flask是轻量级的同步框架&#xff0c;即在单个请求时服务会阻被塞&#xff0c;直到任务完成&#xff08;注意&#xff1a;当前请求被阻塞不会影响到其他请求&#xff09;。 解决异步问题有…

C语言--每日选择题--Day32

如果大家对读研究生和就业不知道如何抉择&#xff0c;我的建议是看大家的经济基础&#xff0c;如果家里不是很需要你们工作&#xff0c;就读研提升自己的学历&#xff0c;反之就就业&#xff1b;毕竟经济基础决定上层建筑&#xff1b; 第一题 1. 下面代码的结果是&#xff1a;…

Paxos 算法

Paxos 算法 介绍 Paxos 算法是第一个被证明完备的分布式系统共识算法。共识算法的作用是让分布式系统中的多个节点之间对某个提案&#xff08;Proposal&#xff09;达成一致的看法。提案的含义在分布式系统中十分宽泛&#xff0c;像哪一个节点是 Leader 节点、多个事件发生的…

百马百担c语言编程

以下是一个百马百担问题的C语言编程实现&#xff1a; #include <stdio.h>int main() { int n, m, k; scanf("%d%d%d", &n, &m, &k); int a[n], b[m], c[k]; for (int i 0; i < n; i) { scanf("%d", &a[i]);…

LangChain 18 LangSmith监控评估Agent并创建对应的数据库

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

ELK高级搜索,深度详解ElasticStack技术栈-下篇

前言&#xff1a;ELK高级搜索&#xff0c;深度详解ElasticStack技术栈-上篇 14. search搜索入门 14.1. 搜索语法入门 14.1.1 query string search 无条件搜索所有 GET /book/_search结果&#xff1a; {"took" : 969,"timed_out" : false,"_shar…

大数据湖项目建设方案:文档全文101页,附下载

关键词&#xff1a;大数据解决方案&#xff0c;数据湖解决方案&#xff0c;数据治理解决方案&#xff0c;数据中台解决方案 一、大数据湖建设思路 1、明确目标和定位&#xff1a;明确大数据湖的目标和定位是整个项目的基础&#xff0c;这可以帮助我们确定项目的内容、规模、所…

Mybatis 分页查询的三种实现

Mybatis 分页查询 1. 直接在 sql 中使用 limit2. 使用 RowBounds3. 使用 Mybatis 提供的拦截器机制3.1 创建一个自定义拦截器类实现 Interceptor3.2 创建分页查询函数 与 sql3.3 编写拦截逻辑3.4 注册 PageInterceptor 到 Mybatis 拦截器链中3.5 测试 准备一个分页查询类 Data…