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 ...
随机推荐
- mysql 分组统计SQL语句
1.按照特定字段: 2.在某一日期范围内: 3.按日.按月统计: 4.动态传入数据库表名称. select <if test="dateType=="d"" ...
- 【运维技术】kafka三实例集群环境搭建及测试使用
kafka三实例集群环境搭建及测试使用 单机搭建分为两部分:1. 软件安装启动 2. 软件配置 软件安装启动: # 切换到目录 cd /app # 获取kafka最新安装包,这边使用的是镜像地址,可以 ...
- 20145309李昊《网络对抗》MSF应用基础
实验内容 掌握metasploit的基本应用方式1.主动攻击——ms08_0672.针对浏览器的攻击——ms11_0503.针对客户端的攻击——Adobe4.成功应用一个辅助模块——scanner/d ...
- linux及安全期中总结——20135227黄晓妍
Linux及安全期中总结 黄晓妍 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ...
- MSF基础攻击实践报告
MSF基础攻击实践 MSF的六个模块:exploit,encoder,payload,aux,post,nops exploit——渗透攻击模块 测试者利用它来攻击一个系统,程序,或服务,以获得开发者 ...
- Java学习笔记心得——初识Java
初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...
- 设置VS快捷代码片段
一.自定义sinppets方式 1.在VS安装路径[D:\vs2013\VC\Snippets\2052\Visual C++]下新建一个snippt文件 2.添加代码 <?xml versio ...
- 【前端】特效-Javascript实现购物页面图片放大效果
实现效果 实现代码: <!DOCTYPE html> <html> <head> <title>购物图片放大</title> <met ...
- Ubuntu16.04下配置pip国内镜像源加速安装【转】
本文转载自:https://blog.csdn.net/yucicheung/article/details/79095742 问题描述 基于国内网速的问题,我们直接pip安装包通常速度非常慢,而且经 ...
- Redis之List 列表
Redis List 列表 Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (42949672 ...