php浮点数比较
本文实例讲述了PHP中两个float(浮点数)比较方法。分享给大家供大家参考。具体如下:
最近在开发一个合同管理系统的时候,涉及到两个浮点数比较,算是把我郁闷惨了。
在N久以前,就不晓得从哪里听来的一个“不要用等号去比较浮点数”的“真理”,自己平时也在用,好像没有出现啥问题,可这次问题总算是来了。
|
1
2
3
4
5
6
7
8
9
|
<?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,小数位)来比较。
|
1
2
3
4
5
6
7
8
9
|
<?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表示两个浮点数值相等
<?php
echo bccomp('1', '2') . "\n"; // -1 小于
echo bccomp('1.00001', '1', 3); // 0 等于
echo bccomp('1.00001', '1', 5); // 1 大于
?>
如果用php的+-*/计算浮点数的时候,可能会遇到一些计算结果错误的问题,比如echo intval( 0.58*100 );会打印57,而不是58
这个其实是计算机底层二进制无法精确表示浮点数的一个bug,是跨语言的
可以用精度函数库解决问题
bcadd — 将两个高精度数字相加
bccomp — 比较两个高精度数字,返回-1, 0, 1
bcdiv — 将两个高精度数字相除
bcmod — 求高精度数字余数
bcmul — 将两个高精度数字相乘
bcpow — 求高精度数字乘方
bcpowmod — 求高精度数字乘方求模,数论里非常常用
bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=”
bcsqrt — 求高精度数字平方根
bcsub — 将两个高精度数字相减

1 /**
2 * 两个高精度数比较
3 *
4 * @access global
5 * @param float $left
6 * @param float $right
7 * @param int $scale 精确到的小数点位数
8 *
9 * @return int $left==$right 返回 0 | $left<$right 返回 -1 | $left>$right 返回 1
10 */
11 var_dump(bccomp($left=4.45, $right=5.54, 2));
12 // -1
13
14 /**
15 * 两个高精度数相加
16 *
17 * @access global
18 * @param float $left
19 * @param float $right
20 * @param int $scale 精确到的小数点位数
21 *
22 * @return string
23 */
24 var_dump(bcadd($left=1.0321456, $right=0.0243456, 2));
25 //1.04
26
27 /**
28 * 两个高精度数相减
29 *
30 * @access global
31 * @param float $left
32 * @param float $right
33 * @param int $scale 精确到的小数点位数
34 *
35 * @return string
36 */
37 var_dump(bcsub($left=1.0321456, $right=3.0123456, 2));
38 //-1.98
39
40 /**
41 * 两个高精度数相除
42 *
43 * @access global
44 * @param float $left
45 * @param float $right
46 * @param int $scale 精确到的小数点位数
47 *
48 * @return string
49 */
50 var_dump(bcdiv($left=6, $right=5, 2));
51 //1.20
52
53 /**
54 * 两个高精度数相乘
55 *
56 * @access global
57 * @param float $left
58 * @param float $right
59 * @param int $scale 精确到的小数点位数
60 *
61 * @return string
62 */
63 var_dump(bcmul($left=3.1415926, $right=2.4569874566, 2));
64 //7.71
65
66 /**
67 * 设置bc函数的小数点位数
68 *
69 * @access global
70 * @param int $scale 精确到的小数点位数
71 *
72 * @return void
73 */
74 bcscale(3);
75 var_dump(bcdiv('105', '6.55957'));
76 // 16.007
php浮点数比较的更多相关文章
- javascript中的浮点数运算
解释一下下面代码的输出 console.log(0.1 + 0.2); //0.30000000000000004 console.log(0.1 + 0.2 == 0.3); //false Jav ...
- 并行计算提升32K*32K点(32位浮点数) FFT计算速度(4核八线程E3处理器)
对32K*32K的随机数矩阵进行FFT变换,数的格式是32位浮点数.将产生的数据存放在堆上,对每一行数据进行N=32K的FFT,记录32K次fft的时间. 比较串行for循环和并行for循环的运行时间 ...
- shell if 浮点数比较
转shell中的浮点数比较http://nigelzeng.iteye.com/blog/1604640 博客分类: Bash Shell shell比较浮点数 由于程序需要,我要判断一个浮点数是否 ...
- PHP浮点数精度问题
这一段时间维护一个类似团购的系统,需要处理订单,也就难免会处理金额 所以有很多PHP的坑 被我狠狠的踩了~~ 首先我们要知道浮点数的表示(IEEE 754): 简言之 就是 埋下了一个大坑 等着你跳 ...
- 关于Linux系统下错误“浮点数异常(核心已转储)”的分析
1.问题发现 有这样一段代码: #include <stdio.h> int main() { int a, b, num1, num2, temp; printf("pleas ...
- C/C++浮点数在内存中的存储方式
一.内存表示 任何数据在内存中都是以二进制的形式存储的,浮点数的表示是把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示,数的小数点位置随比例因子的不同而在一定范围内自由浮动.如下图是3 ...
- IEEE 754 浮点数机器表示标准
32位字长浮点数: 共32位 1 8 23 符号位 解码 尾数 0 + 1 - 移127码 原码,隐含小数点前的首位1 不同数据类型之间转换时,隐藏着一些不容易被察觉的错误,比如int 和 un ...
- js,java,浮点数运算错误及应对方法
js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...
- PHP大数(浮点数)取余
一般我们进行取余运算第一个想到的就是用百分号%,但当除数是个很大的数值,超出了int范围时,这样取余就不准确了. php大数(浮点数)取余函数 /** * php大数取余 * * @param int ...
- 浮点数 (IEEE-754)
浮点数又称"实数",一个浮点数包含三个部分 符号位(S) 阶码 有效数字 S:阶码:有效数字 浮点数是由科学二级制来表示的. 三种类型的浮点数: 短浮点数(32bit): S(b ...
随机推荐
- Web前端学习笔记之前端跨域知识总结
0x00 前言 相信每一个前端er对于跨域这两个字都不会陌生,在实际项目中应用也是比较多的.但跨域方法的多种多样实在让人目不暇接.老规矩,碰到这种情况,就只能自己总结一篇博客,作为记录. 0x01 什 ...
- SQL学习笔记四(补充-2)之MySQL多表查询
阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 #建表 create table depart ...
- linux及安全第六周总结——20135227黄晓妍
总结部分: 操作系统内核三大功能: 进程管理,内存管理,文件系统 最核心的是进程管理 为了管理,首先要对每一个进程进行描述.进程描述符提供了所有内核需要了解的信息. 进程控制模块:task_struc ...
- Duilib嵌入CEF禁止浏览器响应拖拽事件
转载:http://blog.csdn.net/liuyan20092009/article/details/53819473 转载:https://blog.csdn.net/u012778714( ...
- /etc/rc.local 与 /etc/profile
1.用户自己源码安装的软件组要自启动,可以在/etc/rc.local中配置,rc.loacl 是rc.d/rc.local的一个软连接.rc.local -> rc.d/rc.local 2. ...
- shell脚本监控Linux系统性能指标
2016-11-04 22:41 原作者不详 分类: Linux(7) 在服务器运维过程中,经常需要对服务器的各种资源进行监控, 例如:CPU的负载监控,磁盘的使用率监控,进程数目监控等等,以在系统出 ...
- [原][osgearth]API加载earth文件的解析
参考:http://blog.csdn.net/cccstudyer/article/details/17691893 通过\src\osgEarthDrivers\earth\ReaderWrite ...
- Tornado源码分析 --- Cookie和XSRF机制
Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-S ...
- vue 报错 Cannot read property '__ob__' of undefined的解决方法
记不清第n次遇到这个错误了,但是脑子就是不好用,记不住解决办法啊,每次都要找好久才能找到错误,网上还一篇篇的全是错误答案......所以写篇随笔,记录下,方便大家也方便我自己. 网上有人说是组件循环了 ...
- HDU 2577 分情况多维DP
How to Type Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...