C语言标准C89里规定了3种浮点数,float型、double型和long double型,常见的浮点型长度为float型占4个字节,double型占8个字节,long double型长度要大于等于double型,下面将以float型为例进行介绍,double型和long double型只是比float型位数长,原理是一样的 。

float型可以表示的十进制范围是-3.402823466e38~3.402823466e38,而作为同为4个字节的定点数却只能表示-2147483648~2147483647的范围,使用同样的内存空间,浮点数却能比定点数表示大得多的范围,这是不是太神奇了?既然浮点数能表示这么大的范围,那么我们为何不使用浮点数来代替定点数呢?先不说浮点数实现起来比较复杂,有些处理器还专门配置了硬件浮点运算单元用于浮点运算,主要原因是浮点数根本就无法取代定点数,因为精度问题。鱼和熊掌不可兼得,浮点数表示了非常大的范围,但它失去了精度。

ANSI/IEEE Std 754-1985标准

IEEE 754是最广泛使用的二进制浮点数算术标准,被许多CPU与浮点运算器所采用。IEEE 754规定了多种表示浮点数值的方式,下面介绍32位二进制的float浮点类型。它被分为3个部分,分别是符号位S(sign bit)、指数偏差E(exponent bias)和小数部分F(fraction),这三部分都是对应二进制码的。

浮点表示的一般形式为(科学技术法规则):R=(S) * (1 + F) * 2e (R:实数       S:正负符号      F:小数部分     e:指数,不同于指数偏差)。

符号位S:占1位,0代表浮点数是正数,1代表浮点数是负数。

指数偏差E:占8位,范围是0~255,e = E - 127,e为正值表明转换成二进制码后,按科学计数法表达时向左移动了e位, 负值表明向右移动了e位。

小数部分F:占23位,实际上是将浮点数转换成二进制码,再按科学计数法表达,将其小数部分存在F上,由于二进制码按科学计数法表达后,只要值不为0,整数部分就必然为1,所以可以省略整数部分。

例如,3.75的二进制码为11.11,将该二进制码按科学计数法表达为1.111,则向左移动了1位,即e=1,E=e+127=128,F记录的便是小数部分,实际为111000...000。

下面介绍一下小数部分转换为二进制码的方式。类似于整数的形式(如7 = 22 + 21 + 20),小数部分的转换形式为2-1、2-2、2-3、2-4......,例如0.5 = 2-1,即二进制码为0.1,0.05 = 2-5 + 2-6 + 2-9 + 2-10 + 2-13 + 2-14 +...... (可无限循环),即二进制码为0.00001100110011......。如果都以16位计,那么7的二进制码为0000000000000111,0.5的二进制码为0.1000000000000000,0.05的二进制码为0.0000110011001100。这是如何换算出来的呢?且看下面的算法便知:

换算0.5,乘法结果初始为0.5,所有乘数为2,每次用乘法结果 * 乘数,得到新的乘法结果,结果中的整数部分被提取出来,剩余的小数部分继续参加下一次乘法运算,直到剩余小数部分为0,或者无终点(无限循环)。根据表格中的整数部分可知,二进制为0.1。

整数部分

乘数

乘法结果

剩余小数部分

0.

2

0.5

0.5

1

1

0

结束

换算0.05,乘法结果初始为0.05,所有乘数为2,每次用乘法结果 * 乘数,得到新的乘法结果,结果中的整数部分被提取出来,剩余的小数部分继续参加下一次乘法运算,直到剩余小数部分为0,或者无终点(无限循环)。根据表格中的整数部分可知,二进制为0.00001100110011......。

整数部分

乘数

乘法结果

剩余小数部分

0.

2

0.05

0.05

0

2

0.1

0.1

0

2

0.2

0.2

0

2

0.4

0.4

0

2

0.8

0.8

1

2

1.6

0.6

1

2

1.2

0.2

0

2

0.4

0.4

0

2

0.8

0.8

1

2

1.6

0.6

1

1.2

0.2

无限循环

例1:float型浮点数125.5转化成32位二进制浮点数。

125.5的整数和小数部分的二进制码分别为1111101和0.1,于是125.5的二进制码为1111101.1,按科学技术法写为1.1111011*26,即向左移6位,则e=6,E=e+127=133,133的二进制码为10000101。而1.1111011把整数部分的1去掉后,剩下小数部分为1111011,之后补0至23位,构成F。所以125.5的32位二进制浮点数为:

0  10000101  11110110000000000000000

例2:float型浮点数0.5转化成32位二进制浮点数。

类似的,0.5的二进制码为0.1,按科学技术法写为1.0*2-1,即向右移1位,则e=-1,则E=e+127=126,126的二进制码为01111110。而1.0把整数部分的1去掉后,剩下小数部分为0,之后补0至23位,构成F。所以0.5的32位二进制浮点数为:

0  01111110  00000000000000000000000

几个特殊的情形

E=0,F=0时,表示浮点数0,此时浮点数受S影响,表现出+0和-0两种0,但数值是相等的。比如二进制数0x00000000表示+0,二进制数0x80000000表示-0。

E=0,F不等于0时,浮点数为(S) * (F) * 2e,注意e为-126,而不是0-127=-127,而且F是0.xxx格式而不是1.xxx格式,比如0x00000001的浮点数为2-126*2-23=1.4012984643248170709237295832899e-45,而不是20-127*(1+2-23)。E从0变为1,不会产生增加2倍的关系,而是计算公式改变了(恢复正常公式)。

E=255,F不等于0时,表示非数值,也就是说是非法数,例如0x7F800001。

E=255,F=0时,表示无穷大的数,此时浮点数受S影响,例如0x7F800000表示正无穷大,0xFF800000表示负无穷大。做除法时,如果除以0时,结果将被记作0x7F800000。

浮点数的精度

从前文中可以看到,1.xxx这类浮点数中,F部分最小的是2-23,对应的十进制数为1.00000011920928955078125,可以精确表示到小数点后23位,但是一些C语言书上却说float型的有效位只有6~7位,这是为什么呢?原因在于二进制小数与十进制小数没有完全一一对应的关系,二进制小数相比十进制小数来说,是离散而不是连续的,我们来看看下面这些数字:

二进制小数    十进制小数

2-23       1.00000011920928955078125

2-22       1.0000002384185791015625

2-21       1.000000476837158203125

2-20       1.00000095367431640625

2-19       1.0000019073486328125

2-18       1.000003814697265625

这里只需要关注F,上面列出了1.xxx这类浮点数中的6个最小的二进制小数,及其对应的十进制数。可以看到使用二进制所能表示的最小小数是1.00000011920928955078125,其次是1.0000002384185791015625,这两个数之间是有间隔的,如果想用二进制小数来表示8位有效数(只算小数部分,小数点前面的1是隐藏的默认值)1.00000002、1.00000003、1.00000004......这些数是无法办到的,而7位有效数1.0000001可以用2-23来表示,1.0000002可以用2-22来表示,1.0000003可以用2-23+2-22来表示。从这个角度来看,float型所能精确表示的位数只有7位,7位之后的数虽然也是精确表示的,但却无法表示任意一个想表示的数值。

但还是有一些例外的,比如说7位有效数1.0000006这个数就无法用F表示,这也表明二进制小数对于十进制小数来说相当于是离散的,刚好凑不出1.0000006这个数,从这点来看float型所能精确表示的位数只有6位。因此float型的有效位数是6~7位,但这个说法应该不是非常准确,准确来说应该是6位,C语言的头文件中规定也是6位。对于一个很大的数,例如1234567890,它是由于指数E系数而被放大了的,但它的有效位仍然是F所能表示的6~7位有效数字。1234567890用float表示后为1234567936,只有高7位是有效位,后3位是无效的。int型可以准确的表示1234567890,而float浮点数则只能近似的表示1234567890,精度问题决定了float型无法取代int型。

浮点数c语言,C语言浮点数运算相关推荐

  1. 【汇编语言与计算机系统结构笔记03】浮点数的计算机表示,IEEE 754,舍入(rounding),C语言中的浮点数

    本次笔记内容: 04.浮点数的计算机表示 文章目录 IEEE的浮点数标准 IEEE的754标准 浮点数示例 计算机中浮点数二进制表示 浮点数的类型 规格化浮点数(Normalized) 规格化浮点数示 ...

  2. go语言基础之浮点数

    go语言基础之浮点数 这里写目录标题 go语言基础之浮点数 小数的浮点表示法 IEEE754标准 32位单精度浮点数在内存中的存储方式 符号位: sign ,即图中蓝色的方块 偏移后的指数位: bia ...

  3. c语言两个浮点数相加_C语言中两个浮点数或双精度数的模数

    c语言两个浮点数相加 As we know that modules also known as the remainder of the two numbers can be found using ...

  4. c语言的双精度浮点数,什么是双精度浮点数

    问题一:什么是单.双精度浮点数浮点就是小数点位置不确定,比如123.43,6557.521.在C语言中,一般单精度数据类型比如int,数据的范围是2的31次方,而双精度类型的整型比如long int的 ...

  5. 初学C语言中的浮点数

    文章目录 浮点数 C语言规定: 总结: 浮点数的输出 常用的库函数 应用技巧 科学记数法 浮点数 浮点数也称小数或实数, C语言中采用float 和double关键字来定义小数, float 称为单精 ...

  6. C语言中判断浮点数是否等于0

    1.C语言中判断浮点数是否等于0: 2.C语言中判断两个浮点数是否相等: float.double分别遵循R32-24,R64-53的标准.他们尾数的位数分别是23.52,即误差在2^-23,2^-5 ...

  7. c语言里单精度浮点数和双精度浮点数的区别

    单精度浮点数(float)和双精度浮点数(double)在C语言中是两种不同类型的数据.单精度浮点数占用4个字节的空间,精度范围在67位左右:双精度浮点数占用8个字节的空间,精度范围在1517位左右. ...

  8. c语言 整数和浮点数_C ++处理整数和浮点数

    c语言 整数和浮点数 C ++中的所有数字 ( All About Numbers in C++ ) In C++ there are two types of numbers. Ints and f ...

  9. 【C语言】将一个浮点数四舍五入保留两位小数

    [C语言]将一个浮点数四舍五入保留两位小数 第一次做这个题目的时候,我用了一个比较傻的方法:利用强制类型转换可以得到该浮点数的整数部分,然后分别取出十分位.百分位.千分位上的数字,判断千分位上的数字是 ...

  10. 单精度浮点数转十进制C语言,C语言:IEEE754十进制数转二进制单精度浮点数

    1. 背景知识 IEEE754是由IEEE制定的有关浮点数的工业标准.针对于单精度浮点数,其公式如下,S为符号位,只占1位,为0表示正数,为1表示负数.P为指数(阶码),用移码表示,占8位.M为尾数, ...

最新文章

  1. FFmpeg中可执行文件ffmpeg用法汇总
  2. c++ hook 钩子的使用介绍
  3. Actor并发模型入门
  4. PetShop 中的字符串过滤
  5. c语言100以内加减乘除法,一百以内的加减乘除法游戏....
  6. java io异常处理_IO流异常处理
  7. 手动在viewpager的最后一页滑到第一页。
  8. 最新版idea2017+kemulator搭建J2ME开发环境
  9. 航空订票系统C++课程设计
  10. CentOS安装完没有ip地址的解决方法
  11. kali wifi 无线渗透测试 网卡桥接搭建无赖AP
  12. Unity3d的场景音效静音处理
  13. 高速窄脉冲峰值保持设计
  14. win10+ubuntu双系统之三步彻底删除ubuntu系统
  15. linux服务器无法识别u盘,linux系统下不能识别U盘
  16. 计算机网络(谢希仁-第八版)第五章习题全解
  17. kuangbin J - Simpsons’ Hidden Talents
  18. 如何在视频中的对象后面添加图像
  19. 【Java】恭喜你,你的代码获奖了(编写代码的151的建议)
  20. android 群控 网络 adb,安卓群控.sln · 罗金方/结合mini和adb命令,和adb socket实现安卓群控 - Gitee.com...

热门文章

  1. Azure负载均衡器Standard Load Balancer介绍
  2. 菜鸟之webservice(一) 服务端搭建
  3. Centos5搭建vsftpd服务
  4. 继续说一下2016里面的json功能(1)
  5. Add Binary - LeetCode
  6. 防止论坛用户重复登录的方法 .
  7. VISUAL STUDIO 2019 快捷键
  8. 操作系统 VS 编程语言 UNIX VS C语言
  9. 史上最全,100+大数据开源处理工具汇总
  10. base64的c语言实现方法