PHP浮点数用法与问题总结
发布:smiling 来源: PHP粉丝网 添加日期:2014-02-22 08:20:14 浏览: 评论:0
在php浮点数处理函数在php中有很多,包括有如ceil,floor,round,intval 经过他们处理之后可返回我们想要的浮点数小数位了,下面我来介绍一些关于php浮点数用法与问题分析。
一,php浮点数用法
PHP浮点类型取整之ceil — 进一法取整
说明:float ceil (float value)
返回不小于 value 的下一个整数,value 如果有小数部分则进一位。ceil() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。
例子1. ceil() 例子,实例代码如下:
- <?php
- echo ceil(4.3); // 5
- echo ceil(9.999); // 10
- ?>
PHP浮点类型取整之floor — 舍去法取整
说明:float floor (float value)
返回不大于 value 的下一个整数,将 value 的小数部分舍去取整。floor() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。
例子1. floor() 例子,代码如下:
- <?php
- echo floor(4.3); // 4
- echo floor(9.999); // 9
- ?>
PHP浮点类型取整之round — 对浮点数进行四舍五入
说明:float round ( float val [, int precision] )
返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零(默认值)。
例子1. round() 例子,代码如下:
- <?php
- echo round(3.4); // 3
- echo round(3.5); // 4
- echo round(3.6); // 4
- echo round(3.6, 0); // 4
- echo round(1.95583, 2); // 1.96
- echo round(1241757, -3); // 1242000
- echo round(5.045, 2); // 5.05
- echo round(5.055, 2); // 5.06
- ?>
PHP浮点类型取整之intval—对变数转成整数型态
例子intval(),代码如下:
- <?php
- echo intval(4.3); //4
- echo intval(4.6); // 4
- ?>
二,浮点数转成字符串
PHP内置的echo, var_dump, json_encode,字符串拼接等函数(指令)在显示浮点数时都有问题,导致精度丢失.实例代码如下:
- <?php
- $a = 1315537636.338467;
- printf("%f", $a); echo "n";
- echo $a . "n";
- echo $a; echo "n";
- ?>
- /*
- 结果
- 1315537636.338467
- 1315537636.3385
- 1315537636.3385
- */
也就是说,用PHP最顺手的方法将浮点数转成字符串或者显示是不行的,必须使用printf/sprintf将浮点数转成字符串.
三,一个常见问题的解答
不过,我当时遗漏了一点,也就是对于如下的这个常见问题的回答,实例代码如下:
- <?php
- $f = 0.58;
- var_dump(intval($f * 100));
- ?>
为啥输出57
为啥输出是57啊? PHP的bug么?我相信有很多的同学有过这样的疑问,因为光问我类似问题的人就很多,更不用说bugs.php.net上经常有人问…
要搞明白这个原因,首先我们要知道浮点数的表示(IEEE 754):
浮点数,以64位的长度(双精度)为例,会采用1位符号位(E),11指数位(Q),52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示
尾数:表示数据小数点后的有效数字.
这里的关键点就在于,小数在二进制的表示,关于小数如何用二进制表示,大家可以百度一下,我这里就不再赘述,我们关键的要了解, 0.58 对于二进制表示来说,是无限长的值(下面的数字省掉了隐含的1)..
0.58的二进制表示基本上(52位)是:
0010100011110101110000101000111101011100001010001111
0.57的二进制表示基本上(52位)是:
0010001111010111000010100011110101110000101000111101
而两者的二进制, 如果只是通过这52位计算的话,分别是:
0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995
至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999
那你intval一下, 自然就是57了….
可见,这个问题的关键点就是:“你看似有穷的小数,在计算机的二进制表示里却是无穷的”
四,float(浮点数)比较的问题
最近在开发一个合同管理系统的时候,涉及到两个浮点数比较,算是把我郁闷惨了。
在N久以前,就不晓得从哪里听来的一个“不要用等号去比较浮点数”的“真理”,自己平时也在用,好像没有出现啥问题,可这次问题总算是来了,实例代码如下:
- <?php
- $sum = "12300.00";
- $a = "10000.30";
- $b = "2000.30";
- $c = "299.40";
- $sum = (float) $sum;
- $s = (float) ($a+$b+$c);
- var_dump($sum, $s);
- var_dump($sum==$s);
- /*
- 结果是:
- float(12300)
- float(12300)
- bool(false)
- */
后来才知道在PHP中,要比较两个浮点数的大小,可以用bccomp(参数1,参数2,小数位)来比较,实例代码如下:
- <?php
- $sum = "12300.00";
- $a = "10000.30";
- $b = "2000.30";
- $c = "299.40";
- $sum = (float) $sum;
- $s = (float) ($a+$b+$c);
- var_dump($sum, $s);
- var_dump(bccomp($sum,$s,2));
- /*
- 结果:
- float(12300)
- float(12300)
- int(0) // 0表示两个浮点数值相等
- */
bccomp函数具体用法参与PHP手册.
Tags: PHP 浮点数 用法 问题
- 上一篇:PHP入门教程之变量命名规则
- 下一篇:PHP的可变变量名使用方法详解
相关文章
- ·PHP 是什么?(2013-11-12)
- ·Php.ini文件位置在哪里 Php.ini文件找不到(2013-11-12)
- ·PHP 数据类型(2013-11-12)
- ·php 获取当前脚本的url(2013-11-12)
- ·php技术生成静态页面的实现(2013-11-13)
- ·缺陷月项目启动 披露PHP脚本语言漏洞(2013-11-13)
- ·在PHP中全面阻止SQL注入式攻击(2013-11-13)
- ·php生成随机密码的几种方法(2013-11-13)
- ·PHP中使用FCKeditor2.3.2配置(2013-11-13)
- ·如何使用PHP开发高效的WEB系统(2013-11-13)
- ·php:树形结构的算法(2013-11-13)
- ·php4和php5区别(2013-11-13)
- ·php数据库连接(2013-11-13)
- ·如何正确理解PHP的错误信息(2013-11-13)
- ·php页面漏洞分析及相关问题解决(2013-11-13)
- ·当在连接PHP时,抱怨一些数值没有定义参考?(2013-11-27)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)