数制编码详解:二进制八进制十六进制的转换,原码、补码、反码、移码的定义

news2024/12/23 15:40:24

参考资料:《深入理解计算机网络(王达)》

文章目录

  • 一,数制
    • 1.1 基本数制
    • 1.2 不同数制之间的相互转换
  • 二,编码


一,数制

1.1 基本数制

  “数制”是“数据进制”的简称,也就是表示数据逢几进位的意思,如我们常用的十进制就是逢十进位,常见的还有二进制、八进制、十六进制。

  • 二进制(Binary),二进制是计算机运算时所采用的的数制类型,基数是2,二进制数的标志为B,如(1001010)B,也可以用下标2来表示;
  • 八进制(Octal),八进制的标志为O或Q,如(4603)O、(4603)Q,也可以用下标8来表示;
  • 十进制(Decimal),十进制数的标志为D,如(1250)D,也可以用下标10来表示;
  • 十六进制(Hexadecilmal),十六进制的标志为H,如(45A)H,也可以用下标16来表示,十六进制也常用前缀0x来表示。

为什么进制采用2、8、16这种,而不是9或12进制呢?

答:2、8、16分别是2的一次、三次、四次方,这就使得这三种进制之间可以很方便的直接进行互相转换。八进制或十六进制缩短了二进制,但保持着二进制的表达特点。

在这里插入图片描述

1.2 不同数制之间的相互转换

  1. 非十进制数转换为十进制数

  按权相加法:非十进制数转换为十进制数就是把这些非十进制数按位以对应的权值(注意要区分整数位与小数位)展开,然后相加得出相应的十进制值。
在这里插入图片描述

  1. 十进制数转换为非十进制数

  十进制数的整数部分采用“除基逆序取余法”(基数相除,然后逆序取余数),小数部分采用“乘基正序取整法”(基数相乘,然后正序取整数)。这里指的基数就是对应的数制,如二进制的基数为2,八进制基数为8,十六进制基数为16。

  1. 非进制数之间的相互转换

  之前说过,二进制、八进制、十六进制分别是2的一次方、三次方、四次方,因此一位八进制数对应三位二进制数,而一位十六进制数则对应四位二进制数,他们之间的相互转换十分容易。

在这里插入图片描述

  1. 进制转换Java代码:
/**
 * 类描述:进制转换器, 编写一个进制转换器, 可以让数字在 二进制, 八进制, 十进制, 十六进制自由转换
 **/
public class RadixConversion {

    public static void main(String[] args) {
        RadixConversion radix = new RadixConversion();
        // 11101001000.10111B, 1076O, 6374.65Q, 0X7A8C
        radix.conversionDecimal("11101001000.10111B");
        // 825D -> B, 10815.6D -> B, 658D -> O, 9240.65D -> O, 2508D -> H, 5420.82D -> H
        radix.conversionDRadix("825D", Radix.BINARY);
    }

    /**
     * 1.2.1同步练习: 进制转换, 非十进制数转换为十进制数, 将指定参数转换为十进制(Decimal)标志位为D
     * @param str 待转换的参数, 可以是二进制(Binary)标志位为B, 八进制(Octal)标志位为O或Q, 十六进制(Hexadecilmal)标志位为0X或H
     * @return
     */
    public double conversionDecimal(String str) {
        // 1. 首先判断str是什么进制的
        String radix = "10";
        double result = 0.0;
        Map<String, String> map = new HashMap<>();
        Map<Character, Integer> hexadecilmalMapping = new HashMap<>();
        map.put("B", "2");
        map.put("O", "8");
        map.put("Q", "8");
        map.put("D", "10");
        map.put("0X", "16");
        hexadecilmalMapping.put('0', 0);
        hexadecilmalMapping.put('1', 1);
        hexadecilmalMapping.put('2', 2);
        hexadecilmalMapping.put('3', 3);
        hexadecilmalMapping.put('4', 4);
        hexadecilmalMapping.put('5', 5);
        hexadecilmalMapping.put('6', 6);
        hexadecilmalMapping.put('7', 7);
        hexadecilmalMapping.put('8', 8);
        hexadecilmalMapping.put('9', 9);
        hexadecilmalMapping.put('A', 10);
        hexadecilmalMapping.put('B', 11);
        hexadecilmalMapping.put('C', 12);
        hexadecilmalMapping.put('D', 13);
        hexadecilmalMapping.put('E', 14);
        hexadecilmalMapping.put('F', 15);
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (str.contains(entry.getKey())) radix = entry.getValue();
        }
        // 2. 根据不同的进制选择不同的分支, 预处理待转换的数据
        switch (radix) {
            case "2" :
                str = str.replace("B", "");
                break;
            case "8" :
                str = str.replace("Q", "");
                str = str.replace("O", "");
                break;
            case "10" :
                str = str.replace("D", "");
                break;
            case "16" :
                str = str.replace("0X", "");
                str = str.replace("H", "");
                break;
        }
        // 3. 开始转换数据, 要判断有没有小数点的情况, Math.pow(a, b)表示求a的b次幂
        String str_cp = str;
        double right = 0.0;
        if (str.contains(".")) {
            str_cp = str.split("\\.")[0];
            str = str.split("\\.")[1];
            for (int i = 0, j = -1; i < str.length(); i++, j--) {
                right += hexadecilmalMapping.get(str.charAt(i)) * Math.pow(Double.parseDouble(radix), j);
            }
        }
        for (int i = 0, j = str_cp.length() - 1; i < str_cp.length(); i++, j--) {
            result += hexadecilmalMapping.get(str_cp.charAt(i)) * Math.pow(Double.parseDouble(radix), j);
        }
        result += right;
        System.out.println(result + "D");
        return result;
    }

    /**
     * 1.2.2同步练习: 进制转换, 十进制数转换为非十进制数, 将十进制数转换为指定进制数, 使用"除基逆序取余工作"与"乘积正序取整工作"
     * @param str 待转换的十进制数
     * @param radix 待转换的进制, 枚举类型, Radix.type
     * @return 返回radix进制的str
     */
    public String conversionDRadix(String str, Radix radix) {
        StringBuilder sb = new StringBuilder();
        // 1. 去掉十进制数的D符号标注
        str = str.replace("D", "");
        String str_cp = str;
        int base = radix == Radix.BINARY ? 2 : radix == Radix.OCTAL ? 8 : radix == Radix.DECIMAL ? 10 : 16;
        String right = "";
        // 2. 如果有小数位则需要特殊处理
        if (str.contains(".")) {
            str_cp = str.split("\\.")[0];
            double small = Double.parseDouble("0." + str.split("\\.")[1]);
            // 2.1. 待转换的十进制小数部分, 开始小数部分的"乘积正序取整"工作
            int i = 0;
            // 2.2. 只保留三位小数
            while (small > 0 && i < 3) {
                i++;
                small = small * base;
                if (small > 0) {
                    // 2.3. 此处需要获取small小数的整数位与小数位, 然后赋值给对应的对象, 巧妙的使用int+double类型强转
                    int count = (int) small;
                    sb.append(count < 10 ? count
                            : count == 10 ? "A"
                            : count == 11 ? "B"
                            : count == 12 ? "C"
                            : count == 13 ? "D"
                            : count == 14 ? "E" : "F");
                    small = small - count;
                }
            }
            right = "." + sb;
        }
        sb = new StringBuilder();
        // 3. 待转换的十进制整数部分, 开始整数部分的"除基逆序取余"工作
        int num = Integer.parseInt(str_cp);
        while (num >= base) {
            // 3.1. 此处非常巧妙的解决了十六进制中大于等于10的数字需要用字母替代的问题
            int count = num % base;
            sb.append(count < 10 ? count
                    : count == 10 ? "A"
                    : count == 11 ? "B"
                    : count == 12 ? "C"
                    : count == 13 ? "D"
                    : count == 14 ? "E" : "F");
            num /= base;
        }
        if (num > 0) sb.append(num);
        // 3.2. 整数部分是需要逆序的, 此处使用reverse反转方法
        System.out.println(sb.reverse() + right + " " + radix);
        return sb.reverse() + right;
    }

    /**
     * 枚举进制类, 方便标注进制类型
     */
    public enum Radix {
        // 二进制, 八进制, 十进制, 十六进制
        BINARY, OCTAL, DECIMAL, HEXADECILMAL
    }
}

二,编码

  数据编码主要包括“原码”、“反码”、“补码”三种,它们用以不同的形式来表示数据。其实在计算机中负数是以其正数的补码形式来表示的。

  1. 二进制数的真值与字长

    • 真值:就是指二进制数中所有表示值的位数。有符号数的第一位是符号位,那么它的真值就是从第二位开始一直到最后一位。
    • 字长:字长是指计算机一次可以处理的二进制的码位长度,是计算机进行数据存储和数据处理的运算单位。如32位处理器,就是指该处理器的字长为32位,一次能处理32位二进制数。通常16位是一个字,32位是一个双字,64位是两个双字。
  2. 二进制数的四种表现形式

    • 原码:人们约定在一个二进制数前用第一位(最高位)来表示符号,即1代表负,0代表正,这就是原码的概念;

    • 补码:正数的补码和它的原码相同,而负数的补码则是先把除符号位的其他各位数都取反,再在末位(最低位)加1;

      计算机中“模”的概念:

      ​ 我们把一个计量单位称为模或模数,例如时钟是以12进制进行计数循环的,即模为12。在时钟上,时针加上或减去12的整数倍,时钟的位置都不会发生改变。例如14点在舍去模12后成为下午2点;从时钟0点出发逆时针拨十格即减去10小时,也可以看成从0点出发顺时针拨两格,即2点,因此在模12的前提下,-10可以映射为+2。这样就在计算机中将减法问题转换为加法问题了。10和2对模12互为补数。

    • 反码:反码是将除符号位以外的各位都取反得到的进制数,其实反码是原码向补码表现形式转变过程中的一个过渡形式,最终证明它是失败的;

    • 移码:移码是一种特殊的二进制数表现形式,它的编码规则如下:正数的符号位为1,负数符号位为0,真值部分与补码相同。因此相求一个数的移码,只需要先求它的补码,再将符号位取反。

image-20221018172249556

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

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

相关文章

chatGPT的体验,是不是真智能?

目录 &#x1f3c6;一、前言 &#x1f3c6;二、安装 &#x1f3c6;三、普通对话 &#x1f6a9;1、chatGPT的ikun性 &#x1f6a9;2、chatGPT的日常对话 &#x1f3c6;四、实用能力 &#x1f3c6;五、代码改正 &#x1f3c6;六、写代码 &#x1f3c6;七、讲解代码 &#x1f3c6;…

ESXI精简thin磁盘迁移存储位置保留磁盘类型不变-无vc方式

运行2年了ESXI的SSD存储上很多VM并带多层快照&#xff0c;最近磁盘速度异常&#xff0c;迁移到新存储&#xff0c;都是thin磁盘&#xff1b;如有vCenter条件&#xff0c;采用“迁移”即可完美解决&#xff0c;既使磁盘类型thin不变又保留快照结构。如无vCenter条件的操作方式细…

Unity-iOS工程导出Xcode自动构建方法

Unity-iOS发布基本流程首先在Unity中导出Xcode工程&#xff0c;然后在Xcode工程中设置IOS打包的一些流程&#xff0c;诸如引入lib、framework或其他资源、设置签名及其他编译设置、加入编译脚本等等操作。 这些操作如果每次都是在导出Xcode后手动操作&#xff0c;一来浪费时间…

【C++ STL】-- 红黑树的插入实现

目录 红黑树的概念 二叉树搜索树的应用 红黑树节点的定义 红黑树结构 insert 需调整的多情况的核心思维&#xff1a; 需调整的多情况分类讲解&#xff1a; 情况一: 情况二: 情况三: 总结&#xff1a; 代码实现&#xff1a; 对于红黑树是否建立成功的检查 升序打印…

C++--类型转换--1128

1.C语言中的类型转换 分为隐式类型转化、显示强制类型转化。 隐式类型转化用于意义相近的类型&#xff0c;比如int,double,short都是表示数值的类型 int i1; double di; //编译、结果无问题 这里是隐式类型转换。 显示强制类型转换 显示强制类型用于意义不相近的类型&…

Redis Sentinel

高可用架构-Redis Sentinel Replication 缺点 接着之前的Redis Replication 主从复制架构&#xff0c;看似解决了主节点并发过大时&#xff0c;master节点处理繁忙的问题。将一部分读数据的请求交给从节点处理&#xff0c;从而将请求进行分散处理。但是该架构却存在很明显的缺…

基于LEACH的随机网络生成无线传感器网络路由协议的仿真比较(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【深度学习】超详细的 PyTorch 学习笔记(上)

文章目录一、PyTorch环境检查二、查看张量类型三、查看张量尺寸和所占内存大小四、创建张量4.1 创建值全为1的张量4.2 创建值全为0的张量4.3 创建值全为指定值的张量4.4 通过 list 创建张量4.5 通过 ndarray 创建张量4.6 创建指定范围和间距的有序张量4.7 创建单位矩阵&#xf…

【力扣算法简单五十题】23.环形链表

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索…

基于多种优化算法及神经网络的光伏系统控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f389;作者研究&#xff1a;&#x1f3c5;&#x1f3c5;&#x1f3c5;本科计算机专业&#xff0c;研究生电气学硕…

NNDL 实验八 网络优化与正则化(3)不同优化算法比较

文章目录7.3 不同优化算法的比较分析7.3.1 优化算法的实验设定7.3.1.1 2D可视化实验7.3.1.2 简单拟合实验7.3.1.3 与Torch API对比&#xff0c;验证正确性7.3.2 学习率调整7.3.2.1 AdaGrad算法7.3.2.2 RMSprop算法7.3.3 梯度估计修正7.3.3.1 动量法7.3.3.2 Adam算法7.3.4 不同优…

【并发】深度解析CAS原理与底层源码

【并发】深度解析CAS原理与底层源码 什么是 CAS&#xff1f; CAS全称是&#xff08;Compare And Swap&#xff0c;比较并交换&#xff09;&#xff0c;通常指的是这样一种原子操作&#xff08;针对一个变量&#xff0c;首先比较它的内存值与某个期望值是否相同&#xff0c;如…

不就是Redis吗?竟让我一个月拿了8个offer,其中两家都是一线大厂

在高并发的场景Redis是必须的&#xff0c;而 Redis非关系型内存存储不可谓不彪悍。 支持异步持久化达到容灾&#xff1a;速度快、并发高。官方号称支持并发11万读操作&#xff0c;并发8万写操作。惊了吗&#xff1f; 支持数据结构丰富&#xff1a;string&#xff08;字符串&a…

盘点5种最频繁使用的检测异常值的方法(附Python代码)

本文介绍了数据科学家必备的五种检测异常值的方法。 无论是通过识别错误还是主动预防&#xff0c;检测异常值对任何业务都是重要的。本文将讨论五种检测异常值的方法。 文章目录什么是异常值&#xff1f;为什么我们要关注异常值&#xff1f;技术提升方法1——标准差方法2——箱…

【OpenEnergyMonitor】开源的能源监控系统--项目介绍

OpenEnergyMonitor1. 系统框架2.项目组成2.1 emonPi模块:2.1.1 emonpi的安装&#xff1a;2.1.2 emonTx & emonBase 安装2.1.3 emonTx Wifi 安装&#xff1a;2.1.4 添加额外的 emonTx 节点&#xff1a;2.1.5 添加额外的emonTx-节点监控三项电源2.1.6 添加 emonTH 温度节点2.…

【Vue核心】8.计算属性

1. 定义: 要用的属性不存在,要通过已有属性计算得来。 2. 原理 底层借助了objcet.defineproperty方法提供的getter fllsetter. 3. get两数什么时候执行? (1),初次读取时会执行一次。 (2),当依赖的数据发生改变时会被再次调用。 4. 优势 与methods实现相比,内部有缓存机…

进厂手册:Git 学习笔记(详解命令)

文章目录git 对象通过git对象进行文件的保存git对象的缺点树对象构建树对象提交对象高层命令工作区的文件状态git reset hard 咋用以及用错了怎么恢复git checkout vs git resetGit存储后悔药工作区暂存区版本库reset三部曲checkout深入理解tag远程上的相关操作ssh登入一些个人…

[附源码]计算机毕业设计家庭整理服务管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

LeetCode刷题复盘笔记—一文搞懂动态规划之213. 打家劫舍 II问题(动态规划系列第十八篇)

今日主要总结一下动态规划完全背包的一道题目&#xff0c;213. 打家劫舍 II 题目&#xff1a;213. 打家劫舍 II Leetcode题目地址 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一…

快速排序详解

快速排序&#xff0c;简称快排。其实看快速排序的名字就知道它肯定是一个很牛的排序&#xff0c;C语言中的qsort和C中的sort底层都是快排。 快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高&#xff0c;因此经常被采用&#xff0c;再加上快速排序思想----分治法…