如下:
float a = 0.65f; float b = 0.6f; float c = a - b;
此时c为多少?
0.05?错误!
此时c为0.0499999523!
为什么?
其根本原因是计算机所使用二进制01代码无法准确表示某些带小数位的十进制数据。
下面我们来分析下:
我们知道将一个十进制数值转换为二进制数值,需要通过下面的计算方法:
1. 整数部分:连续用该整数除以2,取余数,然后商再除以2,直到商等于0为止。然后把得到的各个余数按相反的顺序排列。简称"除2取余法"。
2. 小数部分:十进制小数转换为二进制小数,采用"乘2取整,顺序排列"法。用2乘以十进制小数,将得到的整数部分取出,再用2乘余下的小数部分,然后再将积 的整数部分取出,如此进行,直到积中的小数部分为0或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来,即先取出的整数部分作为二进制小数的 高位,后取出的整数部分作为低位有效位。简称"乘2取整法"。
3. 含有小数的十进制数转换成二进制,整数、小数部分分别进行转换,然后相加。
例如:将十进制数值25.75转换为二进制数值,步骤如下:
25(整数部分)
25/2=12......1
12/2=6.......0
6/2=3......0
3/2=1......1
1/2=0......1
(25) 10=(11001) 2
0.75(小数部分)
0.75*2=1.5......1
0.5*2=1......1
(0.75) 10=(0.11) 2
(25.75) 10=(11001) 2+(0.11) 2=(11001.11) 2
按照上述方法,我们将0.65及0.6转换为二进制代码:
(0.65)10 = (0.101001100110011001100110011001100110011......)2
(0.6) 10 = (0.10011001100110011001100110011001100110011......)2
后面的省略号表示已经算不完了,后面在无限重复 0011 这段二进制数值。
文章开始部分,我们用的float类型,下面我们来看看float类型是否能存储上面转换出的二进制代码。
目前计算机上存储浮点数值是按照IEEE(电气和电子工程师协会)754浮点存储格式标准来存储的。
IEEE单精度浮点格式共32位,包含三个构成字段:23位小数f,8位偏置指数e,1位符号s。将这些字段连续存放在一个32位字里,并对其进行编码。其中0:22位包含23位的小数f; 23:30位包含8位指数e;第31位包含符号s。如下图所示:
也就是说上面将0.65及0.5转换出的二进制代码,我们只能存储23位,即使数据类型为double,也只能存储52位,这样大家便能看出问题出现的原因了。
截取的二进制代码已无法正确表示0.65及0.5,根据这个二进制代码肯定无法正确得到结果0.05。
如何解决这个问题?知道其根本原因后,我们知道是无法从根本上解决这个问题的,但我们可以有一些曲线救国的方法,下面列举几个:
1. 因为二进制数值可以准确表示整数(可以使用整数转换为二进制方法验证下),所以可以将小数乘以10或100等变成整数,然后做运算,最后再通过除以10或100等获得结果;
2. 通过截取结果的有效小数位数等,来取得最好的近似结果,然后在做处理。
3. 对于可以用有限长度的二进制数值表示的十进制数值,可以使用存储位数大于其长度的数据类型。
解决方案正在补充中……,若各位有什么好的方法也可以提出来!
以上解决方案需要按照使用的实际情况来决定使用哪种方法。
来源:http://www.2cto.com/kf/201007/52889.html
相关推荐
PHP 7中的正确舍入,任意精度的十进制浮点运算
的相加减问题是,出现了浮点运算不准的情况,看来都说解释型语言对于浮点运算都会有问题的说法是真的。 首先看一段代码: <?php $a = 0.1; $b = 0.7; var_dump(($a + $b) == 0.8); 打印出来的值居然为 boolean ...
PHP MySQL程序开发中的乱码产生原因及解决方案分析.pdf
项目解决方案 项目解决方案 项目解决方案 项目解决方案 项目解决方案 项目解决方案
PHP LAMP环境搭建的所有问题及解决方案Linux .pdf
Informatica,大数据管理解决方案,数据集成管理解决方案,数据安全解决方案
本文讲的是mysql大数据分库和分表 php解决方案。 mysql分库分表方案、mysql 分库方案、php实现mysql分库分表、mysql高并发解决方案。
PHP微信小程序解决方案PhpMall针对小程序特性,提供了商城跟PHP后台进行交互的解决方案,帮助用户高效完成小程序开发,项目持续更新中...。 DiyGw是一个基于TwoTHink开源的内容管理框架,由Onethink基础上升级到...
PHP下ajax跨域的解决方案之jsonp实例分析.docx
这就给我们的应用提出了挑战,如何建设一套高弹性的应用机制非常重要,接下来就让我们一起来实现这样的方案。 适用人群: 初中级PHP开发工程师|企业在职PHP开发工程 资源太大,传...
在PHP5.5以上版本运行ecshop和ecmall出现的问题及解决方案
php中文乱码解决方案 详细的PHP中文乱码解决方法
PHP数学运算与数据处理实例分析_.docx
本毕设旨在开发一款基于PHP语言的网络数据包分析工具,旨在提供一个方便快捷的解决方案,帮助用户快速分析网络数据包。该工具将提供以下功能: ## 1. 网络数据包捕获 本工具将提供捕获网络数据包的功能,用户可以...
IEEE754-1985二进制浮点运算标准 MATLAB中所有数值都是使用64bit表示的。根据754-1985规定,第一位是符号指示位(S),接下来的11位是指数部分(C),最后称为尾数的52位为小数部分(F),指数的基是2。 X64表示的区间...
BAOCMS多城市解决方案 PHP
本书作者为活跃在php开发一线、具有丰富php开发经验的专家,他们把实践中积累的大量经验技巧和有针对性的问题的解决方案,结合sitepoint论坛上的一些常见问题的解决方案编写了本书。本书采用大量实际案例进行深入...
3.用户可指定操作数的数目(至少二个、至多四个),如果指定的操作数超过2个,应该随机出现括号用于改变运算顺序。 4.用户可以指定结果是否允许出现负数。 5.用户可以指定每个操作数的最大值 6.用户可以指定题目的...