浮点数的表示和精度

如果a>0,那么1+a一定大于1吗?在数学上,答案是肯定的。但在计算机上,答案就与a的大小和浮点数的精度有关了。在matalb上,可以作以下计算:

>> a=1/2^52

a =

2.220446049250313e-016

>> 1+a>1

ans =

1

>> a=1/2^53

a =

1.110223024625157e-016

>> 1+a>1

ans =

0

可见,当a等于1/2^53时,1+a>1是不成立的。

1 浮点数

IEEE754定义了单精度浮点数和双精度数浮点数,即float和double。float有32bit,double有64bit。它们都包括符号位、指数和尾数。

符号位

指数

尾数

float

31(1)

30-23(8)

22-0(23)

double

63(1)

62-52(11)

51-0(52)

符号位有1bit,0表示正、1表示负。设一个数的指数是e,指数部分的值是bias+e。加上一个bias是为了表示负数。 float的bias是127,double的bias是1023。指数全0或全1有特殊含义,不算正常指数。

float的指数部分有8bit,可以取值1~254,减掉127,得到对应的指数范围-126~127。

double的指数部分有11位,可以取值1~2046,减掉1023,得到对应的指数范围-1022~1023。

这里的指数是以2为底的,同样尾数也是二进制的。IEEE754要求浮点数以规范形式存储,即小数点前有1位非零数字。 对于二进制数,非零数字只有1。所以IEEE754在存储时省略了这个小数点前面的1,只存储小数点后面的位。

2 误差

看个例子,设:

double a=0.2;

在PC上,我们可以看到a对应的存储区数据是:

9A 99 99 99 99 99 C9 3F

PC的数据是小尾的,即低位字节在后,将其写成高位字节在前,得到:

3F C9 99 99 99 99 99 9A

可见符号位为0。指数位是0x3FC,即1020,减掉1023,得到指数-3。尾数是999999999999A。所以完整的数字就是16进制的1.999999999999A乘上2^-3。即:

a=(1+9*(1/16+1/16^2+...+1/16^12)+10/16^13)*2^-3

(1/16+…+1/16^12)可以用等比级数求和公式a1*(1-q^n)/(1-q)计算,其中a1=1/16,q=1/16,n=12,因此:

a=(1+9*(1-1/16^12)/15+10/16^13)*2^-3

用windows的计算器计算上式,得到

a=0.2000 0000 0000 0000 1110 2230 2462 5157

这也不是精确解,但已经可以看到用double表示0.2时存在的误差。这个例子说明在用有限字长的二进制浮点数表示任意实数a可能引入误差。 设实数a的指数为e,尾数位数为n,显然:

误差

3 精度

可以把机器精度定义为满足条件

fl(1+ε)>1

的最小浮点数ε。其中fl(1+ε)是1+ε的浮点表示。显然double的机器精度是1/2^52。float的机器精度是1/2^23。 matlab内部采用double,1+1/2^53对double来说就是1,所以1+1/2^53不会大于1。

对于规范数来说,因为小数点前默认有个1,所以float的有效数字是24bit,对应8位十进制有效数字; double的有效数字是53bit,对应16位十进制有效数字。

4 特殊的浮点数

前面提到浮点数的指数全0或全1有特殊含义,让我们来看看这些特殊的浮点数:

指数和尾数都是全0表示0。根据符号位不同可以分为+0和-0。

指数全0,尾数不为全0,这些数是非规范数,即尾数部分不假设前面存在小数点前的1。 或者说这些数太接近0了,因为指数已经不能再小,所以这些数不能写成规范形式。 例如:double数0000 0000 0000 0001的尾数是0 0000 0000 0001,即1/2^52,对应的数是1/(2^52)*2^-1022,即4.9406564584124654e-324。

指数全1,尾数全0表示无穷大,即inf。根据符号位不同可以分为+inf和-inf。

指数全1,尾数不为全0表示NaN,即Not a Number,不是数。尾数最高位为1的NaN被称作QNaN(Quiet NaN)。 尾数最高位为0的NaN被称作SNaN(Signalling NaN)。通常用QNaN表示不确定的操作,用SNaN表示无效的操作。

在计算机内部,double就是一个64位数。从0x0000 0000 0000 0000~0xFFFF FFFF FFFF FFFF,每个64位数都对应一个浮点数或NaN。 我写了一个小程序,按照64位无符号整数的顺序打印出典型的浮点数。 表格的第一列是浮点数的内部表示。为了便于阅读,按大尾顺序输出。第二列是对应的浮点数。 第三列是注释,对于非规范数和规范数给出了由内部表示计算数值的matlab算式。 注意在C/C++中,2^52要写成pow(2.0,52.0)。

0000 0000 0000 0000

0.0000000000000000e+000

+0

0000 0000 0000 0001

4.9406564584124654e-324

1/(2^52)*2^-1022

000F FFFF FFFF FFFF

2.2250738585072009e-308

.5*(1-.5^52)/(1-.5)*2^-1022

0010 0000 0000 0000

2.2250738585072014e-308

1.0*2^-1022

0010 0000 0000 0001

2.2250738585072019e-308

(1+1/2^52)*2^(-1022)

001F FFFF FFFF FFFF

4.4501477170144023e-308

(1+.5*(1-.5^52)/(1-.5))*2^-1022

0020 0000 0000 0000

4.4501477170144028e-308

1.0*2^-1021

3FF0 0000 0000 0000

1.0000000000000000e+000

1.0

3FF0 0000 0000 0001

1.0000000000000002e+000

1.0+1/(2^52)

3FFF FFFF FFFF FFFF

1.9999999999999998e+000

1+.5*(1-.5^52)/(1-.5)

4000 0000 0000 0000

2.0000000000000000e+000

1.0*2^1

7FEF FFFF FFFF FFFF

1.7976931348623157e+308

(1+.5*(1-.5^52)/(1-.5))*2^1023

7FF0 0000 0000 0000

1.#INF000000000000e+000

+INF

7FF0 0000 0000 0001

1.#SNAN00000000000e+000

SNaN

7FF7 FFFF FFFF FFFF

1.#SNAN00000000000e+000

SNaN

7FF8 0000 0000 0000

1.#QNAN00000000000e+000

QNaN

7FFF FFFF FFFF FFFF

1.#QNAN00000000000e+000

QNaN

8000 0000 0000 0000

0.0000000000000000e+000

-0

8000 0000 0000 0001

-4.9406564584124654e-324

-(1/(2^52)*2^-1022)

800F FFFF FFFF FFFF

-2.2250738585072009e-308

-(.5*(1-.5^52)/(1-.5)*2^-1022)

8010 0000 0000 0000

-2.2250738585072014e-308

-(1.0*2^-1022)

8010 0000 0000 0001

-2.2250738585072019e-308

-((1+1/2^52)*2^(-1022))

801F FFFF FFFF FFFF

-4.4501477170144023e-308

-((1+.5*(1-.5^52)/(1-.5))*2^-1022)

8020 0000 0000 0000

-4.4501477170144028e-308

-(1.0*2^-1021)

BFF0 0000 0000 0000

-1.0000000000000000e+000

-1.0

BFFF FFFF FFFF FFFF

-1.9999999999999998e+000

-(1+.5*(1-.5^52)/(1-.5))

C000 0000 0000 0000

-2.0000000000000000e+000

-(1.0*2^1)

FFEF FFFF FFFF FFFF

-1.7976931348623157e+308

-((1+.5*(1-.5^52)/(1-.5))*2^1023)

FFF0 0000 0000 0000

-1.#INF000000000000e+000

-INF

FFF0 0000 0000 0001

-1.#SNAN00000000000e+000

SNaN

FFF7 FFFF FFFF FFFF

-1.#SNAN00000000000e+000

SNaN

FFF8 0000 0000 0000

-1.#IND000000000000e+000

QNaN

FFFF FFFF FFFF FFFF

-1.#QNAN00000000000e+000

QNaN

从表中可以看到,double内部表示的设计是很有规律的,按照对应64位数的顺序依次为 +0、正非规范数、正规范数、正无穷大、符号位为正的NaN、-0、负非规范数、负规范数、负无穷大、符号位为负的NaN。

double内部表示的设计保持了浮点数的有序性。即:如果正double数a

4 结束语

float和int都是32bit,但float的尾数只用了23bit。int的精度高于float,float的表示范围大于int。float牺牲精度换取了更大的表示范围。 double的尾数是52bit,高于32bit的int,所以用dobule表示int不会有精度损失。 double是科学计算的常用类型,了解double的内在和限制,有助于我们更好地使用它。

喜欢 (1)or分享 (0)

matlab的单精度浮点数,浮点数的表示和精度_单精度浮点数的表示相关推荐

  1. 计算机组成原理浮点数左移规则,2020考研计算机组成原理知识点:浮点数的表示和运算...

    2020年计算机考研复习已经开始,新东方在线在此整理了2020考研计算机组成原理知识点:浮点数的表示和运算,希望能帮助大家! 浮点数的表示和运算 1. 浮点数的表示 1)浮点数的表示范围; 浮点数是指 ...

  2. 计算机浮点数乘法过程,计算机中单精度浮点数运算详解

    写在前面 在PA_2019fall中有一项任务是完成CPU中的浮点数运算,这也是我第一次认真的思考了一下真实的计算机中CPU是如何进行的浮点数运算 在写PA的过程中一头雾水,从迷茫,到困惑,到弄懂,到 ...

  3. js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法

    浏览器处理数字运算时精度丢失的方法 为什么0.1 + 0.2 不等于0.3.因为计算机不能精确表示0.1, 0.2这样的浮点数,计算时使用的是带有舍入误差的数 并不是所有的浮点数在计算机内部都存在舍入 ...

  4. 关于python的浮点数类型、以下_python入门教程Python 浮点数数据类型详解 [学习 Python 必备基础知识][看此一篇就够了]...

    python基础语法.jpg 您的"关注"和"点赞",是信任,是认可,是支持,是动力...... 如意见相佐,可留言. 本人必将竭尽全力试图做到准确和全面,终其 ...

  5. python浮点数怎么运算_python中实现精确的浮点数运算详解

    为什么说浮点数缺乏精确性? 在开始本文之前,让我们先来谈谈浮点数为什么缺乏精确性的问题,其实这不是Python的问题,而是实数的无限精度跟计算机的有限内存之间的矛盾. 举个例子,假如说我只能使用整数( ...

  6. C语言学习(十一)小数在内存中是如何存储的?定点数与浮点数各自的优势在哪?规格化浮点数与非规格化浮点数又表示什么?

    C语言学习(十一)小数在内存中是如何存储的?定点数与浮点数各自的优势在哪?规格化浮点数与非规格化浮点数又表示什么? 浮点数与定点数 小数在内存中以浮点数形式存储.浮点数并不是一种数值分类,他和整数.小 ...

  7. 代码库_单精度浮点减法器

    代码库_单精度浮点减法器 前言 README 外围电路 flag signal 前言 浮点减法器的实现和加法器几乎一样,唯一不同的就是"扩展尾码"的加法操作要改写为减法,然后编译器 ...

  8. 在计算机领域,半精度、单精度、双精度的定义,以及多精度计算和混合精度计算的区别。

    在计算机系统的内存中,半精度是16bit,单精度是32bit,双精度是64bit. signed bit符号位,有效数字的符号位 Exponent 阶码或者叫指数,以10^Exponent表示 Sig ...

  9. java中单精度_java单精度和双精度的区别

    描述 为什么会有精度问题? 计算机处理数据都涉及到数据的转换和各种复杂运算,比如,不同单位换算,不同进制(如二进制十进制)换算等,很多除法运算不能除尽,比如10÷3=3.3333.......无穷无尽 ...

最新文章

  1. Field、CopyField、DynamicField的一些简介,用法
  2. centos7删除符号链接_面试 | Linux 下软链接和硬链接的区别
  3. AM8不能下任何载附件及所有聊天记录无法登记
  4. [Python图像处理] 三十.图像量化及采样处理万字详细总结(推荐)
  5. Linux下Gcc 的编译过程
  6. php保存附件到指定服务器,如何在PHP中将电子邮件附件保存到服务器?
  7. python模拟密码有效性检测功能_检查密码有效性(Django/Python)
  8. C++学习—— mutable和 extern
  9. VScode 搭建 django 开发环境(Win Python3.71 django1.11.11)
  10. 用于UML前端展示的jsuml2插件
  11. ff14离线查看客户端日志小技巧
  12. 固高运动控制卡学习6 --编码器
  13. 【C51单片机】密码锁设计
  14. bitblt与StretchDIBits
  15. 电子工程师 嵌入式开发者的嘉年华最强攻略
  16. 中国人口总数、老龄人口占比及2040人口年龄结构变化预测
  17. 深入Netty源码解析内存优化技巧
  18. ubuntu添加桌面快捷方式图标
  19. Kali安装GVM(openvas)教程并更改用户密码
  20. bind server.c

热门文章

  1. 紫砂壶型和泥料适配茶叶
  2. 电路中的原理图中电阻电容的选择
  3. Linux驱动模块加载和卸载以及设备注册与注销
  4. dart null safty中list?.isEmpty报错的处理
  5. Linux安装Anaconda3过程详解
  6. 低表示差异(LRG)
  7. 【Spring 工厂,西安富士通Java笔试题
  8. django orm级联_第19天,Django之ORM进阶续
  9. 前端 | (二)各种各样的常用标签 | 尚硅谷前端html+css零基础教程2023最新
  10. 正弦波随机信号matlab,matlab自相关函数