【C语言】计算机是如何存储整数和小数的?

news2024/12/23 14:12:05

文章目录

  • 前言
  • 一、正整数和0
  • 二、负整数
  • 三、小数
    • 1、定点数
      • (1)什么是定点数
      • (2)表示精度
      • (3)表示范围
      • (4)优缺点
    • 2、浮点数
      • (1)什么是浮点数
      • (2)将小数转为浮点数
      • (3)浮点数在计算机中的存储格式
      • (4)浮点数中的指数部分如何存入计算机
      • (5)表示精度
      • (6)表示范围
      • (7)优缺点
  • 四、答疑
    • 1、定点数表示法已经被淘汰了吗?
    • 2、为什么说整数的存储其实也是用定点数存储格式?
    • 3、硬件FPU单元
  • 参考资料


前言

一条数轴上的数可以分为整数和小数,整数包括正整数、负整数和0,小数也包括正小数和负小数。

人类借助"+“、”-“、”."、"0~9"等符号以及约定俗成的摆放顺序来表示和存储不同的数字。

但计算机只认识0和1,要想在计算机中表示和存储不同的数字,就需要借助一套完整的存储规则。

对于不同类型的数字,存储规则也是不一样的。


一、正整数和0

正整数和0在计算机中的表示方法最为简单,就是转化的二进制数本身。

如3在计算机中就表示为0000_0011。

二、负整数

先说答案,负整数在计算机中采用补码表示。

转化过程:
先取得负整数绝对值的二进制形式(注意符号位为1),得到原码,按位取反(符号位不用管)得到反码,再加1即可得到补码。

举一个例子:
-7的原码为1000_0111,反码为1111_1000,补码为1111_1001。

问:为什么负数要以这样的形式存储在计算机中呢?

答:为了方便进行数值运算。如要实现-7+3 = -4,

在计算机中是这样进行的:

1111_1001 + 0000_0011 = 1111_1100

而-4的原码为1000_0100,反码为1111_1011,补码为1111_1100,这样就跟上面的计算结果相吻合了。

而如果不用补码,假设用1000_0111表示-7,其中左边第一位为符号位,那进行如下计算:

1000_0111 + 0000_0011 = 1000_1010,结果并不能表示-4。

这里涉及补码向十进制的转换,反过来就行:

-4的补码为1111_1100,先减一,为1111_1011,按位取反为1000_0100,即-4的原码。

三、小数

先说答案,现代计算机采用浮点数的方式保存小数。

但早期的计算机使用定点数的方式保存小数。

1、定点数

(1)什么是定点数

注意:定点数不是指一类数字,而是指一种小数在计算机中的存储方法。

定点数就是指小数点位置不动的小数存储方式。

定点数存储法其实就是将小数直接转化为二进制存储在计算机中。这跟正整数和0的存储方法是一样的,其实正整数和0也是按照定点数的方式存储的,只是此时小数部分全为0省略了而已。

如用8bit空间存储定点数,约定前4位为整数部分,后4位为小数部分。很显然这样小数点的位置就固定在了第3位和第4位之间。
在这里插入图片描述

这样做的好处就在于能一眼看出所要表示的数字。

比如这里就能一眼看出所要表达的小数为1011.0111

转化为十进制就是:
在这里插入图片描述

现在我们来分析定点数表示法的精度和范围。

(2)表示精度

首先精度在这里就是表示数学上的准确数值与计算机中实际存储的数值的误差。

为了说明这个误差有时候是不可避免的,我举一个例子:

数学上的π是一个无限不循环小数,要存储它理论上需要一块无限大的空间,但这是不可能的,计算机的存储空间是有限的,因此只能存储π的近似值,由此误差就产生了。

以上面的8bit空间为例,其中4位表示小数,因此这种情况下精度是1/16,即0.0625。

这里结合之前写的博文【科普】精度和分辨率的区别与联系

可以知道,由于没有系统误差,因此这里的精度等价于分辨率。

这样就好理解了,4位小数的分辨率就是1/16。

(3)表示范围

如上所述的8bit空间可以存储的最大数字为1111_1111=8+4+2+1+1/2+1/4+1/8+1/16=15.9375

最小可以表示的正数为0000_0001=1/16=0.0625。

(4)优缺点

优点:

——简单易懂:定点数表示法相对于其他复杂的表示方法(如浮点数)来说更加简单和直观,易于理解和实现。

——固定精度:定点数具有固定的位数来表示整数和小数部分,因此精度是固定的。这在某些应用中可能是有益的,可以保持一致的精度。

——运算速度快:相比于浮点数运算,定点数运算通常更加高效,因为定点数的运算只涉及整数运算,无需处理浮点数的特殊规则。

缺点:

——固定精度:虽然固定精度是定点数的一个优点,但在某些情况下也可能成为缺点。当处理非常大或非常小的数值时,固定的精度可能不足以保持所需的准确性,导致舍入误差。

——难以表示极小或极大的数值:定点数通常不适用于表示极小或极大的数值范围。对于超出表示范围的数值,定点数无法准确表示,因此需要使用更高精度的表示方法。

这里可以举一个例子:

普朗克长度约等于1.6x10^-35米,即0.00000000000000000000000000000000016m,用定点数表示为(也就是转化为二进制):

0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011010100101011010010110110111111110000111101000001111。

大约需要20多个字节才能存储得下。

地球的质量5.965×10²⁴kg,即59650000000000000000000000千克,用定点数表示为(也就是转化为二进制):

11000101010111011000001111101010111100011100110010101101011101010000000000000000000000

需要十几个字节才能存储得下。

注意:这里用了一个整数的例子,既在说明极大的数字用定点数方式存储的缺点,也在说明整数也可以用定点数表示,只是此时全部位都用来表示整数。

可以发现在表示极大或极小的数字时,定点法非常消耗存储空间。

为了解决上述问题,更复杂的浮点数诞生了。

2、浮点数

(1)什么是浮点数

跟定点数一样,浮点数也不是指一类数字,它指的是一种小数在计算机中的存储方法。

浮点数就是指小数点位置会变动的小数存储方式。

浮点数表示法跟科学计数法很相似:
在这里插入图片描述
Float:要表示的小数
s:符号位,1表示负数,0表示正数
M:尾数
E:指数

(2)将小数转为浮点数

举两个例子:

–将15.625转化为浮点数
首先将其转化为二进制1111.101(这其实就是定点数表示法)
用浮点形式表示为:
在这里插入图片描述

–将0.01875转化为浮点数
首先将其转化为二进为0.0011
用浮点形式表示为:
在这里插入图片描述

可以看到小数点位置发生了变动,因此称为浮点数,浮即浮动,点即小数点

(3)浮点数在计算机中的存储格式

要存储一个浮点数,需要存储三个东西:符号、指数和尾数。

这里C语言提供了两种浮点数封装格式:float和double
在这里插入图片描述

其中符号位为0就表示正数,符号位为1就表示负数。

通过上面的例子可以发现尾数取值范围为 [1,2),也就是说尾数的整数部分一定为1,这样就没必要浪费空间存储整数部分了。对于1.111101只要存储后面的111101就行。因此计算机真正存储的只是尾数的后半部分。

指数部分可能为正数也可能为负数,如果再添加一个符号位按照补码的方式存储未免过于繁琐,这里聪明的科学家设计了一个巧妙的方法。

(4)浮点数中的指数部分如何存入计算机

先说答案,以float为例,在存入指数前,先加上127,这样即使指数为负数,加上127后也会变为正数。这样就不用再用补码表示负数了。

因此,读取指数时也要先减去127。

举2个例子:

15.625浮点形式为:
在这里插入图片描述
符号位为0,尾数为1.111101,只存储后面的111101,指数部分为3,加上127后为130,其二进制为1000_0010。

因此15.625在计算机中的最终存储格式为0_10000010_11110100000000000000000。

0.01875浮点形式为:
在这里插入图片描述
符号位为0,尾数为1.1,只存储后面的1,指数部分为-3,加上127后为124,其二进制为0111_1100。

因此0.01875在计算机中的最终存储格式为0_01111100_10000000000000000000000。

:为什么要加上127?
:这个偏移值是按照下式计算的:
在这里插入图片描述

如float的指数占用8bit,那么其偏移值就是
在这里插入图片描述

而double的指数占用11bit,其偏移值为
在这里插入图片描述

到此,我们可以发现,计算机中存储的尾数并不是真正的尾数;存储的指数也并不是真正的指数。

(5)表示精度

这里以0.35举例对比一下两种表示法的精度

用32bit来存储0.35,规定1位为整数部分,其余为小数部分,用定点法表示为0.0101100110011001100110011001100,再转回来就是0.34999999962747097,依然存在误差 0.00000000037252903。

将0.35首先转化为浮点数形式:1.01100110011001100110011001100*2^(-2),如果是float格式(同样是32bit),则尾数部分只能截取01100110011001100110011,指数部分为-2+127=125,即0111_1101
因此0.35的float格式为0_0111_1101_01100110011001100110011

再将其转化为十进制为1.01100110011001100110011*2^(-2),即0.3499999940395355,误差为0.0000000059604645,比用定点法表示的误差略大。

因此可以得出结论

同样的存储空间,浮点数相比定点数的表示精度更低。

这也就是浮点数能表示更大范围数字所付出的代价。

也就是说使用相同存储空间,定点数精度较高,但范围小;浮点数范围大,但精度较低。凡是皆有代价,不是吗?

(6)表示范围

在float的内存分布中,指数部分占据8位,可以表示0~255,由于进行了偏移,因此可以表示负数,能表示的指数范围为-127 ~ 128。

真的吗?

float实际只能存入的指数范围为-126 ~ 127。因为指数部分全为1或全为0用于表示其他特殊情况了。

在这里插入图片描述

1)规格化的值
一般情况下,即指数在(0,255)范围内时,转化规则为:

真实的尾数=1.存储的尾数
真实的指数=指数部分-偏移值

因此规格化的值能表示的范围为:
在这里插入图片描述

其中1.11…11中一共有24个1。

2)非规格化的值
当指数位全为0时,转化规则发生了变化:

真实的尾数=0.存储的尾数
真实的指数=1-偏移值

当尾数的所有二进制位都为 0 时,整个浮点数的值就为 0:
如果符号 sign 为 0,则表示 +0;
如果符号 sign 为 1,则表示 -0。

因此非规格化的值能表示的范围为:
在这里插入图片描述

这里有必要解释一下

偏移值为127,因此真实的指数为1-127=-126

指数部分是不变的,变的只有尾数部分,真实的尾数范围为0~0.11…11

因此非规格化的值能表示的范围为:
在这里插入图片描述
非规格化的值能表示的最接近0的值为:

在这里插入图片描述

在这里插入图片描述

3)无穷大
当指数全为1,且尾数部分为0,则表示无穷大。

s=0表示正无穷;s=1表示负无穷

4)NaN
当指数全为1,且尾数部分不为0,则表示是一个无效的数字NaN。

从上面的讨论可以看出,float的整体表示范围为:
0~+∞

其中规格化的值的表示范围为:
在这里插入图片描述
即:
在这里插入图片描述

非规格化的值表示范围为:
在这里插入图片描述
其中1.11…11*2^(-127)略小于 2 ^ (-126)

当符号位为1时,float表示负数,此时float表示的数字范围为
-∞~ 0

同样,double能表示的数字范围为:
在这里插入图片描述

(7)优缺点

优点:

——大范围:浮点数表示法可以表示非常大和非常小的数值范围,例如可以表示非常大的天文数字和非常小的微观粒子。
——硬件支持:现代计算机硬件对浮点数运算进行了优化,可以高效地执行浮点数计算。

缺点:
——精度损失:相同存储空间,定点数精度更高
——舍入误差:由于尾数位数的限制,进行浮点数计算时可能会发生舍入误差,特别是在连续的浮点数运算中,舍入误差可能逐渐积累导致结果偏离预期。
——复杂度和成本:浮点数计算的硬件实现相对复杂,同时存储和处理浮点数所需的内存和计算资源也更多,相比于定点数来说更加昂贵。

同样举上面的例子:

普朗克长度约等于1.6x10^-35米,用二进制表示为:

1.010101000100100001001001001100101101001011100111001*2^(-116)

由于float尾数最多只能存23位,因此尾数存储01010100010010000100100,指数为-116,加上127为11,即0000_1011,因此普朗克长度的float存储形式为:

0_0000_1011_01010100010010000100100

我们只用了32bit就存储了如此小的一个数,相比用定点数存储方式空间消耗量缩小了5倍以上。

但细心的读者也发现了,由于位数限制我在存储尾数的时候做了舍入,由此也造成了舍入误差。

其实除了部分以5结尾的小数外(如0.5,0.125),大部分小数都无法精确存储,0.35都不能精确存储。

四、答疑

1、定点数表示法已经被淘汰了吗?

定点数表示法在某些嵌入式系统、数字信号处理、特定硬件平台和低功耗设备等领域仍有应用,没有完全被浮点数表示法取代。

2、为什么说整数的存储其实也是用定点数存储格式?

对于short、int、 long这样的整数,我们可以将它们视为没有小数部分的定点数,即小数部分为零,小数点在末尾。这样,整数的存储可以看作是定点数存储格式的特例。

这样数字在计算机中的存储格式可以这样划分:

整数采用定点数格式存储;小数采用浮点数格式存储。

也正是因为浮点数和小数紧紧绑定在一起,因此可以视浮点数和小数这两个概念是等价的,可以不用区分。

但严格上来说,浮点数是小数在计算机中的存储格式。

3、硬件FPU单元

硬件浮点单元(Floating-Point Unit,FPU)是一种在计算机处理器中集成的硬件组件,专门用于执行浮点数运算。FPU提供了硬件级别的浮点数运算指令集和计算单元,能够高效地执行浮点数的加减乘除、平方根、取整等运算。

高级芯片中集成有FPU,如Intel的Core系列和AMD的Ryzen系列、智能手机SOC、GPU芯片、FPGA芯片、高端型号的STM32微控制器(如STM32F4和STM32H7系列)。

对于不带硬件FPU的STM32芯片,仍然可以进行浮点数运算,但是需要使用软件库来模拟浮点数运算,这被称为软件浮点数库。软件浮点数库通过软件算法实现浮点数运算,但相比硬件浮点单元,其性能较低。


参考资料

1、https://fishc.com.cn/thread-67214-1-1.html
2、http://c.biancheng.net/view/vip_1764.html
3、二进制小数转十进制https://jisuan5.com/binary-to-decimal/

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

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

相关文章

Linux——搭建jdk环境

标题Linux——搭建jdk环境 Linux搭建jdk,案例采用jdk8 1.检查linux位数(64和32位) [rootnode1 /]# getconf LONG_BIT 642.下载对应的linux JDK包,这里使用jdk8 下载jdk8 : 链接: https://www.oracle.com/java/technologies/downloads/#java8 3、上…

苹果又撕下了国产手机遮羞布,国内消费者最爱iPhone

618结束之后,各个国产手机品牌都说自己表现优秀,比去年增长了多少多少,不过随着分析机构给出具体的数据,国产手机可谓被撕下了遮羞布,国内消费者最爱的还是iPhone。 分析机构指出618期间iPhone的销量高达562万部&#…

【互斥锁与信号量】线程通信:互斥锁(mutex)与信号量(semaphore)

目录 0. 互斥锁与信号量 同步互斥概述 1. 互斥锁 1.1 互斥锁的概念 1.2 互斥锁初始化:pthread_mutex_init函数 1.3 互斥锁上锁:pthread_mutex_lock函数 1.4 互斥锁解锁:pthread_mutex_unlock函数 1.5 销毁互斥锁:pthread_…

chatgpt赋能python:Python重写父类方法:在OOP编程中的应用

Python重写父类方法:在OOP编程中的应用 在Python的面向对象编程范式中,继承是一种非常重要的概念。当我们声明一个类时,我们可以通过继承来扩展类的功能并避免重复编写代码。在这个过程中,很可能你会碰到需要重写父类方法的情况。…

17.RocketMQ之死信队列

highlight: arduino-light 1.5 死信队列 当一条消息初次消费失败,消息队列 RocketMQ 会自动进行消息重试;达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息,此时,消息队列…

flutter 简介 flutter 能为我们做什么

flutter 简介 flutter 能为我们做什么 前言一、什么是Flutter?二、Flutter的特点和优势三、Flutter与其他跨平台框架的比较总结 前言 陆陆续续已经写了60多篇的flutter 的文章了,本篇文章就来说说我对flutter 的简单看法 一、什么是Flutter&#xff1f…

【Rust】安装

文章目录 1.官网下载2.安装3.安装验证4.打开本地文档5.安装插件6.HelloWorld①新建项目目录使用VSCode打开②新建rs文件③编译④运行 7.HelloCargo①新建项目目录使用VSCode打开②cargo build③cargo run④cargo check⑤为发布构建 8.更新与卸载 1.官网下载 官网地址&#xff…

c++11 标准模板(STL)(std::basic_ostream)(一)

定义于头文件 <ostream> template< class CharT, class Traits std::char_traits<CharT> > class basic_ostream : virtual public std::basic_ios<CharT, Traits> 类模板 basic_ostream 提供字符流上的高层输出操作。受支持操作包含有格式…

工业读码器在工业生产上应用的优势有哪些?

工业读码器是一种用于读取和解码条形码、二维码等信息的设备&#xff0c;一般广泛应用于工业生产中。可以辅助企业进行工业生产流程、物料等方面的管理。下面我们就一起来了解一下&#xff0c;工业读码器在工业生产上应用的优势有哪些&#xff1f; 工业读码器在工业生产上应用…

基于Java学生公寓管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

华为OD机试真题 Python 实现【工作安排】【2023Q1 100分】

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出3、说明 一、题目描述 小明每周上班都会拿着自己的工作清单&#xff0c;工作清单内包含n项工作&#xff0c;每项工作都有对应的耗时时长&#xff08;单位h&#xff09;和报…

回归预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM、BiLSTM多输入单输出回归预测

回归预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM、BiLSTM多输入单输出回归预测 目录 回归预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM、BiLSTM多输入单输出回归预测效果一览基本描述程序设计参考资料 效果一览 基本描述 1.Matlab实现QPSO-BiLSTM、PSO-BiLSTM、BiLSTM神经…

【综合布线技术】网络杂谈(17)之什么是综合布线系统

涉及知识点 什么是综合布线系统&#xff0c;综合布线的特点&#xff0c;综合布线的标准&#xff0c;综合布线 6 个子系统&#xff0c;综合布线系统的构成&#xff0c;深入了解综合布线技术。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多内容可去其主页关注…

chatgpt赋能python:Python量化指标库介绍

Python量化指标库介绍 Python是一种高级编程语言&#xff0c;因其简单易用、开源免费、生态环境完备等优点&#xff0c;已成为量化分析领域的首选编程语言之一。随着金融市场越来越复杂&#xff0c;金融量化分析的需求也日益增长。为了满足这一需求&#xff0c;Python量化指标…

【OJ比赛日历】快周末了,不来一场比赛吗? #07.01-07.07 #11场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-07-01&#xff08;周六&#xff09; #3场比赛2023-07-02…

Yarn的实现原理

Yarn作为分布式集群的资源调度框架&#xff0c;它的出现伴随着Hadoop的发展&#xff0c;使Hadoop从一个单一的大数据计算引擎&#xff0c;成为一个集存储、计算、资源管理为一体的完整大数据平台&#xff0c;进而发展出自己的生态体系&#xff0c;成为大数据的代名词。 Yarn的发…

谷歌云:全面推出 AlloyDB for PostgreSQL 与数据库迁移服务

【本文由Cloud Ace 整理发布。Cloud Ace 是谷歌云全球战略合作伙伴&#xff0c;拥有 300 多名工程师&#xff0c;也是谷歌最高级别合作伙伴&#xff0c;多次获得 Google Cloud 合作伙伴奖。作为谷歌托管服务商&#xff0c;我们提供谷歌云、谷歌地图、谷歌办公套件、谷歌云认证培…

在Android Studio 中运行React Native 项目

项目根目录执行命令安装开发依赖 yarn检查项目SDK、NDK、JDK否配置正确 点击 Android Studio 里点击大象 全部下载完毕&#xff0c;点击运行按钮&#xff0c;编译项目 连接真机的两种方式 无线连接 adb devices adb tcpip 5555 #连接端口默认5555 adb connect 192.168.0…

低功耗测距语音方案,4路PWM调光,三合一语音芯片WTV890-B004

随着智能门锁市场的不断发展&#xff0c;人们对于智能化、便捷化的需求也越来越高。在这个背景下&#xff0c;深圳唯创知音研发出了三合一语音芯片——WTV890-B004。这款创新产品集低功耗红外测距、语音播放和4路PWM调光功能于一体&#xff0c;为您打造一个高效、智能化方案。 …

上传自己的npm依赖包

有时候我们需要对某个依赖包的源码进行修改进行使用&#xff0c;但我们又不能对已有的源码官网进行上传更新&#xff0c;这时&#xff0c;我们可以获取依赖包进行修改后&#xff0c;自行部署到https://npmjs.com中 1.官网https://npmjs.com中注册一个账号&#xff08;账号&…