从数论的角度上探究计算机是如何储存整数与浮点数

计算机存储整数的方法

计算机存储整数主要采用两种方式:无符号整数和有符号整数的存储。每种存储方式都基于二进制系统,但处理正负数的方式不同。

1. 无符号整数的存储

无符号整数只表示非负数。在无符号整数存储中,所有的位(bit)都用于表示数值的大小,没有位被用来表示符号。

存储范围
  • 8位无符号整数:可以存储从0到255的数值。
  • 32位无符号整数:可以存储从0到4,294,967,295的数值。

2. 有符号整数的存储:补码

有符号整数可以表示正数、负数和零。计算机采用“补码”(Two’s complement)格式来存储有符号整数。

补码的定义和计算

补码的计算方式如下:

  • 正数和零:直接使用其标准的二进制表示。
  • 负数
    1. 取其正数的二进制表示。
    2. 将所有位取反(0变为1,1变为0)。
    3. 最后结果加一。

3.通过数论来推导整数的储存规则

对于0-255的每一个数 Xi , Xi mod 256 得到的余数与 另一个数 Xj mod 256 得到的余数都不相同

对于0-255 数论上定义这是 mod 256 的一个最小非负完全剩余系 {0,1,2…254,255}

实际上计算机储存的8 Bit数据就是 2^8的一个完全剩余系

  • 如果我们储存的整数是无符号的,那么我们的储存范围就是0-255,储存的是mod 256 的一个最小非负完全剩余系 {0,1,2…254,255}

  • 如果我们储存的整数是有符号的,那么我们储存范围就是 -128-127,储存的是mod 256 的一个剩余系 {-128,-127…126,127}

如何转化负数?

  • -128 -127 -126 -125 为例

我们有同余方程 -128=128 mod 256

====> Dec (128)=Bin (1000 000)

我们有同余方程 -127=129 mod 256

====> Dec (129)=Bin (1000 0001)

我们有同余方程 -126=130 mod 256

====> Dec (130)=Bin (1000 0010)

  • 这里我们和 127 126 125 做对比

====> Dec (127)=Bin (0111 1111)

====> Dec (126)=Bin (0111 1110)

====> Dec (125)=Bin (0111 1101)

这里我们注意到储存有符号整数的剩余系中,对于负数的储存都是转化为同余数之后在储存

这帮发明计算机的大爹们就注意到负数的首位都是1,正数的首位都是0
于是这个首位就被定义为了符号位

示例
  • -1的补码:在8位系统中,因为 (-1 \equiv 255 \mod 256),因此-1的补码就是255的二进制表示11111111
  • -127的补码:(-127 \equiv 129 \mod 256),因此-127的补码是129的二进制表示10000001

计算机储存浮点数规则

1. IEEE754浮点数标准

  • 单精度float:32位bit(四字节)储存, 符号S位占1bit, 指数E占8bit, 尾数M占23bit

  • 双精度double:64位bit(八字节)储存, 符号S位占1bit, 指数E占11bit, 尾数M占52bit

2. 指数 E 是什么?

指数 E 是个无符号整数,表示 float 时,一共占 8 bit,所以它的取值范围为 0 ~ 255。

但因为指数可以是负的,所以规定在存入 E 时在它原本的值加上一个中间数 127(2^7-1),这样 E 的取值范围为 -127 ~ 128。

表示 double 时,一共占 11 bit,存入 E 时加上中间数 1023,这样取值范围为 -1023 ~ 1024。

3. 为什么指数要加127?

这里储存指数位的数学原理还是数论中的剩余系

这里还是以 8 bit 为例子

如果指数位E只是正数的话 0000 0000 就可以储存 0 - 255

比如:

Dec (127)=Bin ( 0111 1111)

但是对于浮点数来说指数位也是存在负数的

比如储存 Dec (0.5)=Bin (0.1) = Bin (1x2^-1)

E = -1

对于负整数的储存,我们采取补码的形式来解决(即对剩余系中的负数 +256进行映射)。

补码中我们使用符号位来记录数值的正负。

想一下我们补码的符号位是怎么来的

在补码中我们采取对剩余系中负数+256进行映射

{-128,-127…127} 映射到 {0,1,2…254,255}

这就导致了负数的首位都是1,而正数的首位都是0。

但是在浮点数的储存中,我们已经有一个符号位来记录了。

为了避免符号位的重复,我们选择对剩余系中的每一个数字都进行映射

在标准的float储存中,指数位是 8 Bit (0000 0000)

于是我们的映射就是对每一个数都 +127 进行同余映射

{-127…128} 映射到 {0,1,2…254,255}

与补码映射的对比

  • 补码映射:对含负数的剩余系中的负数+256进行映射

{-128,-127…127} 映射到 {0,1,2…254,255}

0 -----> 0
127 ----> 127
-128 —> 128

  • 指数位映射:对含负数的剩余系中的每一个+127进行映射

{-127…128} 映射到 {0,1,2…254,255}

0 -------->128
-127 ------>0
-10 ------>117

这里映射选取的值取决于剩余系中的最小负数

4. 指数位与尾数位的特殊值

  • 指数 E 非全 0 且非全 1:规格化数字,按上面的规则正常计算
  • 指数 E 全 0,尾数非 0:非规格化数,尾数隐藏位不再是 1,而是 0(M = 0.xxxxx),这样可以表示 0 和很小的数
  • 指数 E 全 1,尾数全 0:正无穷大/负无穷大(正负取决于 S 符号位)
  • 指数 E 全 1,尾数非 0:NaN (Not a Number)

这个特殊值的规定导致了float的 E的实际取值范围不是-127-128,而是-126-127

因为-127映射之后是0,表示为0000 0000 全0特殊值
因为128映射之后是255,表示为1111 1111 全1 特殊值

5. 浮点数的储存范围

这里以float类型为例

上面我们得知float类型的指数E取值范围是[-126,127],尾数的最大值为1.111…(即小数点后23位)

所以float类型的规格最大储存值是

(1+(1−2−23))×2127 ≈3.4028235×10^38

同理也可以得到规格最小储存值是

(0.000…1)×2^-126 ≈2-23x2-126 =2^-149 ≈1.40129846×10^−45

6.浮点数为什么会有精度损失

如果我们现在想用浮点数表示 0.2,它在转化为二进制的时候会发生尾数的截断

0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。

尾数位的限制
因为float类型只有23位尾数位,而double类型有52位尾数位,这意味着在达到这些位数后,剩余的位数将被截断。这个截断就是精度损失的来源。即使是使用double类型,虽然精度更高,但如果数字的二进制表示超过52位,仍然会有精度损失。

在float中最多会转化 23 bit 二进制小数
在double中最多会转化 52 bit 二进制小数

因此,当你在编程中使用浮点数时,可能会注意到例如0.2 + 0.1不精确等于0.3,而是一个非常接近0.3但略有不同的数。这种现象是由于二进制表示中的截断和舍入误差造成的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 本地库引入了依赖但编译时找不到

在使用 IDEA 开发 Maven 项目的过程中,有时会遇到本地库引入了依赖,但编译时报找不到这个依赖,可以使用命令处理。 打开 Terminal。 执行清理命令。 mvn clean install -Dmaven.test.skiptrue执行更新命令。 mvn -U idea:idea

怎么清除3D模型杂质?---模大狮模型网

在进行3D建模过程中,模型可能会受到各种杂质的影响,这些杂质可能来自于模型本身的结构问题、导入导出过程中的错误、或者是不当的编辑操作所留下的痕迹。清除这些杂质是保证模型质量和渲染效果的关键步骤之一。本文将介绍几种常见的清除3D模型杂质的方法…

【C++】适配器· 优先级队列 仿函数 反向迭代器

目录 适配器:适配器的应用:1. 优先级队列:仿函数:更深入的了解仿函数:一个关于不容易被注意的知识点: 2. 反向迭代器:list && vector: 适配器: 我们先来谈来一下…

最新IntelliJ IDEA 2024.1 安装和快速配置教程

IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版 文章目录 IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版前言 第一步: IntelliJ IDEA 2024.1安装教程第 0 步&…

activiti初次学习

源代码地址:https://gitee.com/ZSXYX/activiti.git​ 1、安装插件 首先安装下图所示activiti,不确定是哪个插件有用的,有时间可排除下 在resources下创建一个文件夹:processes,右键,新建 生成: 选中act.bpmn20.xm…

Android 使用ping命令判断当前网络状态

一. 介绍 ping命令是用来测试和诊断网络连接问题的基本命令,当然我们的终端设备(手机/平板/车机)都可以用这个命令来判断当前网络是否有流量的状态,本篇文章主要介绍Linux的ping命令,因为Android系统也是使用了Linux内…

【面经】操作系统/Linux

1、计算机的五大单元 电脑的五大单元包括:输入单元、输出单元、控制单元、算数逻辑单元、存储单元五大部分。其中CPU占有控制、算术逻辑单元,存储单元又包含内存与辅助内存; 2、什么是操作系统 操作系统:负责管理协调我们计算机…

汽车车灯用肖特基二极管,选什么型号好?

肖特基二极管种类繁多,有低压降肖特基二极管、通用型肖特基二极管、快速恢复型肖特基二极管、高功率肖特基二极管、汽车级肖特基二极管等等,其中低压降肖特基二极管和汽车级肖特基二极管是二极管厂家东沃电子的核心优势产品。关于东沃电子推出的低压降肖…

Android 接入MQTT服务器

加入MQTT库 加入库可以直接下载对应的jar包,也可以在build.gradle里导入,然后加载进入。 这里直接在build.gradle加库 dependencies {implementation(libs.appcompat)implementation(libs.material)implementation(libs.activity)implementation(libs…

【k8s】:深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用

【k8s】:深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用 1、什么是亲和性?2、节点亲和性(Node Affinity)2.1 硬性节点亲和性规则(required)2.2 软性节点亲和性规则&#xf…

如何制作二维码电子画册?轻松入门,快速上手!

在当今数字化时代,二维码电子画册成为了企业推广和信息传递的重要工具之一。相比传统纸质画册,二维码电子画册不仅环保节能,而且可以通过扫描二维码轻松获取更多详细信息,为用户提供了更加便捷的阅读体验。 今天就教大家如何制作二…

【Java开发指南 | 第三篇】Java 空行、强制类型转换及基本数据类型

读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 Java 空行强制类型转换Java 基本数据类型内置数据类型引用类型 Java 空行 空白行或者有注释的行,Java 编译器都会忽略掉。 强制类型转换 当需要将一个数据类型转换为另一个数据类型时&#xff0c…

浅尝 express + ORM框架 prisma 的结合

一、prisma起步 安装: npm i prisma -g查看初始化帮助信息: prisma init -h查看初始化帮助信息结果: Set up a new Prisma projectUsage$ prisma init [options] Options-h, --help Display this help message --datasource-provider …

Intewell-Hyper II_V2.1.1_工业实时操作系统软件版本发布

Intewell-Hyper II_V2.1.1_工业实时操作系统软件版本发布 Intewell-Hyper II_V2.1.1 版本号:V2.1.1 版本特点 新增V1.3.2分支上SHV构型合并及问题回归 版本或修改说明 增加功能: 1.V1.3.2分支上SHV构型合并及问题回归 2.适配NewPre3102和NewPre3101…

node+vue3的websocket前后端消息推送

nodevue3的websocket前后端消息推送 前期写web项目时,前端获取数据的方式一般是向后端发起数据请求,然后后端向前端发送数据,然后对数据进行渲染,这是最常规的一种数据通讯方式,适用于绝大部分前后端分离的项目 实际…

java的ConcurrentHashMap深入理解

概要 怎么保证线程安全: 在初始化数组时用了cas操作,sizectl作为占位标志(U.compareAndSwapInt(this, SIZECTL, sc, -1);获取数组中的元素是否已经有了,用Volatile修饰数组(保证可见性)&#…

边缘计算网关有哪些优势?-天拓四方

随着信息化、智能化浪潮的持续推进,计算技术正以前所未有的速度发展,而边缘计算网关作为其中的重要一环,以其独特的优势正在逐步改变我们的生活方式和工作模式。本文将详细解析边缘计算网关的优势。 首先,边缘计算网关具有显著的…

【好书推荐6】《Excel函数与公式应用大全for Excel 365 Excel 2021》

【好书推荐6】《Excel函数与公式应用大全for Excel 365 & Excel 2021》 写在最前面《Excel函数与公式应用大全for Excel 365 & Excel 2021》关键点内容简介作者简介前言/序言目录 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光&…

Linux之命令行参数的原理以及实现,环境变量限时增加删除和永久增加删除以及代码获取环境变量

个人主页:点我进入主页 专栏分类:C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂 一.命令行参数 1.1main函数参数 在我们学习c语言时我们的main函数…

Vue - 5( 16000 字 Vue2 入门级教程)

一:Vue 初阶 1.1 组件自定义事件 在 Vue 中,组件间通过自定义事件进行通信是一种常见的模式。自定义事件允许子组件向父组件发送消息,也可以在组件内部进行事件的绑定、触发和解绑。让我们详细讲解这些知识点。 1.1.1 组件自定义事件 在 …
最新文章