php浮点型以及精度问题
2015-06-24 11:33
633 查看
浮点型(也叫浮点数 float,双精度数 double 或实数 real)
浮点数的形式表示:
LNUM [0-9]+DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})
浮点数的精度问题
浮点数的精度有限。尽管取决于系统,PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16。非基本数学运算可能会给出更大误差,并且要考虑到进行复合运算时的误差传递。此外,以十进制能够精确表示的有理数如 0.1 或 0.7,无论有多少尾数都不能被内部所使用的二进制精确表示,因此不能在不丢失一点点精度的情况下转换为二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999999991118...。
所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。
NaN
某些数学运算会产生一个由常量 NAN 所代表的结果。此结果代表着一个在浮点数运算中未定义或不可表述的值。任何拿此值与其它任何值进行的松散或严格比较的结果都是 FALSE。由于 NAN 代表着任何不同值,不应拿 NAN 去和其它值进行比较,包括其自身,应该用 is_nan() 来检查。
浮点数比较的问题
永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等,但是你可以比较出浮点数的后几位是否相等<?php if((0.01 + 0.003) == 0.013) echo 'equal'; else echo 'unequal'; //结果为unequal /** * bccomp 比较做操作数和右操作数,以整型的形式返回结果 * @param string $left_operand 左操作数 * @param string $right_operand 右操作数 * @param int $scale 用于比较小数点后的位数默认为2 * @return int 0表示两个数是相等的,1表示左操作数大,-1表示右操作数大 **/ $iResult = bccomp((0.01 + 0.003), 0.013, 3); if(!$iResult) echo 'the two operands are equal'; elseif($iResult > 0) echo 'left_operand is larger than the right_operand'; elseif($iResult < 0) echo 'right_operand is larger than the left_operand'; else echo 'unknown result'; //the two operands are equal ?>
相关文章推荐
- php计算多维数组中所有值总和的方法
- PHP定时执行任务的实现
- PHP GBK UTF8互转
- PHP运行出现Notice : Use of undefined constant 的解决办法
- php-fpm backlog 项的调整
- 在php4下可用,简单的php数组转成json格式,
- 如何在Zend Studio中使用Zend Debugger
- PHP将Excel导入数据库及数据库数据导出至Excel的方法
- php的web开发中关于上传文件的几种方法的总结
- php-fpm配置笔记
- php如何在某个时间上加一天?一小时? 时间加减(转)
- php异常处理方法实例汇总
- php-fpm - 启动参数及重要配置详解
- PHP-FPM参数优化
- ByteArrayOutputStream(字节数组输出流)的一个例子,与ByteArrayInputStream作一比较
- 分享一个自己写的基于TP的关系模型(2)
- TP 查询某一条件字段 并 排序
- php数组索引与键值操作技巧实例分析
- 如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
- PHP-FPM参数优化