首页 > 其他分享 >二进制中为什么负数是正数取反再加一

二进制中为什么负数是正数取反再加一

时间:2024-07-03 12:20:16浏览次数:14  
标签:表示 二进制 补码 取反 负数 正数

二进制中的负数表示有一个重要的概念是补码,它是由对应正数二进制取反后再加 1 得到的。但是经常忘记为什么要这么表示,这里结合 chatgpt 解释做个简单的总结。

补码(Two's Complement)设计的逻辑来自于简化和统一计算机中有符号数的表示和运算。其设计逻辑可以追溯到计算机科学中的一些基本需求和目标。以下是补码设计逻辑的详细解释:

1. 有符号数的表示

目标: 在计算机中,需要一种方法来表示正数和负数,同时要确保运算的简便性和一致性。

2. 符号位的使用

思路: 使用最高位(最左边一位)作为符号位。0表示正数,1表示负数。这是因为使用最高位作为符号位可以直接决定数的正负,同时剩余的位可以用于表示数值部分。

3. 简化运算

需求: 希望计算机能够使用相同的电路(主要是加法器)来处理加法和减法。

实现:

  • 对于加法,直接进行二进制加法。
  • 对于减法,将减法转换为加法,通过加上一个负数来实现。

4. 负数的表示

挑战: 如何表示负数使得上述需求能够被满足?

这里我们可以假设给定一个正数,例如 5 的8位二进制是 0000 0101,那么我们该如何设计-5 呢?

很显然,最重要想实现的目的是 5+-5=0,也就是 0000 0101 + x = 0000 0000, 手动算一下减法,x= 1111 1011。观察一下规律你会发现,x 其实就是 0000 0101取反再加 1。

整理一下,如下:

补码的引入:

  • 按位取反加1: 补码的核心思想是,将一个数的负数表示为该数的按位取反再加1。

例如,对于8位系统中的数字:

  • 正数 5 的二进制表示是 0000 0101。
  • 负数 -5 的表示过程是:
    1. 将 5 的二进制按位取反:1111 1010
    2. 加1:1111 1011
      因此,-5 的补码表示是 1111 1011。

5. 运算一致性

验证: 通过补码表示,负数可以直接参与加法运算,而无需额外的减法电路。

例如,计算 5 + (-5):

  • 5 的二进制表示是 00000101
  • -5 的补码表示是 11111011

二者相加:

  00000101
+ 11111011
  ----------
  100000000  (由于是8位系统,只取低8位,结果为 00000000)

结果为 00000000,表示0,运算正确。

6. 统一零的表示

优势: 使用补码表示法,零只有一种表示形式,即 00000000,这简化了零的处理逻辑,避免了符号-绝对值表示法中正零和负零的问题。

7. 溢出检测简化

溢出检测: 在补码表示法中,溢出可以通过简单的逻辑操作检测到。例如:

  • 两个正数相加结果为负数
  • 两个负数相加结果为正数

这可以通过检查结果的符号位来实现。

设计逻辑总结

补码的设计逻辑旨在简化和统一计算机中有符号数的表示和运算。其主要优势包括:

  • 符号位的直观使用
  • 负数的补码表示使加法和减法运算一致
  • 零的唯一表示形式
  • 简化的溢出检测

通过这些设计,补码有效地解决了在计算机中处理有符号数的各种挑战,成为现代计算机系统中广泛采用的表示方法。

标签:表示,二进制,补码,取反,负数,正数
From: https://www.cnblogs.com/marsggbo/p/18281374

相关文章

  • CentOS 7基于开源项目制作openssh9.8p1 rpm二进制包修复安全漏洞CVE-2024-6387 ——
    2024年7月1日,官方发布openssh9.8版本,修复了安全漏洞CVE-2024-6387。此处主要基于开源项目https://github.com/boypt/openssh-rpms.git制作,之前也有写过类似的文章,这里就不再赘述。CentOS5/6/7基于开源项目制作openssh9.6p1rpm包——筑梦之路_centos6openssh9.6rpm-CSD......
  • 正整数N转换成一个二进制数2
    题目网址:https://bzoj.org/p/Z1600Description输入一个不大于32767的正整数N,将它转换成一个二进制数Input输入只有一行,包括一个整数n(n<=32767)Output输出只有一行,包含一个二进制数,数字之间以空格分开Samples输入数据1100输出数据11100100Sol:转化二进制法......
  • Linux下二进制可执行文件分析 (nm,readelf,objdump 命令使用)
    最近在调试一些问题,发现几个命令很实用,记录一下。一 背景    也许大家都遇到过这种场景,就是有二进制代码,比如深度分析下此文件到底是什么格式的图片等,这篇文章就记录我分析下二进制可执行文件的过程,已经自己读写二进制文件的一些坑。分析的二进制执行文件为linux下......
  • Day 30 | 122.买卖股票的最佳时机II、55. 跳跃游戏 、45.跳跃游戏II、 1005.K次取反后
    122.买卖股票的最佳时机II本题解法很巧妙,本题大家可以先自己思考一下然后再看题解,会有惊喜!https://programmercarl.com/0122.买卖股票的最佳时机II.html给定一个数组,它的第i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成......
  • 基于二进制软件包 —安装 MySQL-8.0.28
    #!/bin/bash##********************************************************************#Author: Kevin#Date: 2024-06-23#FileName: install_mysql.sh#Description: Thetestscript#Copyright(C): 2024Allrightsreserved#****************************......
  • MySQL-5.7.38 基于二进制包一键安装脚本
    #!/bin/bash##********************************************************************#Author: Kevin#Date: 2024-06-23#FileName: install_mysql.sh#Description: Thetestscript#Copyright(C): 2024Allrightsreserved#****************************......
  • C++数据格式化5 - uint转换成十六进制字符串&二进制的data打印成十六进制字符串
    1.关键词2.strfmt.h3.strfmt.cpp4.测试代码5.运行结果6.源码地址1.关键词关键字:C++数据格式化字符串处理std::stringinthex跨平台应用场景:int型的数据打印成十六进制字符串二进制的data打印成十六进制字符串。2.strfmt.h#pragmaonce#include<stri......
  • C++数据格式化5 - uint转换成十六进制字符串&二进制的data打印成十六进制字符串
    1.关键词2.strfmt.h3.strfmt.cpp4.测试代码5.运行结果6.源码地址1.关键词关键字:C++数据格式化字符串处理std::stringinthex跨平台应用场景:int型的数据打印成十六进制字符串二进制的data打印成十六进制字符串。2.strfmt.h#pragmaonce#include<......
  • verilog实现格雷码和二进制码的相互转换
    目录格雷码的介绍二进制码转化为格雷码格雷码转化为二进制码verilog实现代码格雷码的介绍在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(GrayCode),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。在数字系统......
  • 详谈JavaScript 二进制家族:Blob、File、FileReader、ArrayBuffer、Base64
    详谈JavaScript二进制家族:Blob、File、FileReader、ArrayBuffer、Base64:https://blog.csdn.net/weixin_43025151/article/details/129743443?ops_request_misc=&request_id=&biz_id=102&utm_term=JavaScript%E4%B8%AD%E7%9A%84Blob%E4%BD%A0%E7%9F%A5%E9%81%93%E5%A4%9A%E......