一、常见问题

用 PHP 做计算时经常会遇到精度带来的问题,下面来看两个常见的例子:

1. 运算比较

下面表达式输出的结果不是相等

<?php 

echo 2.01 - 0.01 == 2 ? '相等' : '不相等';  // 不相等

2. 类型转换

下面表达式输出的结果不是201(如果想输出你想要的结果,需要先转 string 再转 int):

<?php

$num = intval(2.01 * 100);
var_dump($num); // int(200)

你也许会觉得很奇怪,然而这并不是 PHP 的 bug,如果想深入了解可以参考鸟哥的两篇文章:

  1. 关于PHP浮点数你应该知道的(All ‘bogus’ about the float in PHP)
  2. PHP浮点数的一个常见问题的解答

二、BC MATH

用 PHP 提供的 BC MATH 系列数学函数可以解决上面的问题。对于任意精度的数学计算, BC MATH 提供了支持用字符串表示的任意大小和精度的数字的二进制计算,最多为2147483647-1(或0x7FFFFFFF-1)。

下面用 BC MATH 提供的函数解决上面的问题。

1. 运算比较

bccomp — 比较两个任意精度的数字:

<?php

$num = bccomp(2.01 - 0.01, 2, 2);
var_dump($num); // int(0)

注:如果两个数相等返回 0, 左边的数比较右边的数大返回 1, 否则返回-1。

2. 类型转换

bcmul — 2个任意精度数字乘法计算:

<?php

$num = bcmul(2.01, 100, 0);
var_dump($num); // string(3) "201"
var_dump(intval($num)); // int(201)

注:返回结果为字符串类型

使用 BC MATH 系列数学函数可以让我们减少失误,避免不必要的错误,如需查看详细参数和其它函数的使用,请查阅 PHP 官方文档:http://php.net/manual/zh/book.bc.php


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。

马燕龙个人博客:http://www.mayanlong.com

马燕龙个人微博:http://weibo.com/imayanlong

马燕龙Github主页:https://github.com/yanlongma

PHP 基础篇 - PHP 的 BC MATH 系列数学函数的更多相关文章

  1. iOS math.h数学函数

    在实际工作中有些程序不可避免的需要使用数学函数进行计算,比如地图程序的地理坐标到地图坐标的变换.Objective-C做为ANSI C的扩展,使用C标准库头文件<math.h>中定义的数学 ...

  2. Leetcode基础篇30天30题系列之数组:模拟计算法

    作者:丁宋涛 数组:加一 题干: 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个整 ...

  3. 【OpenGL基础篇】——使用面向对象方法封装OpenGL函数(二)

    今天封装了一个Line类.负责在昨天写的窗体上绘制线条. OpenGL画图是通过给glBegin函数设置參数达成的,绘制线条有三个不同的參数: GL_LINES : 绘制连接两个点的线段(绘制的端点位 ...

  4. SQL Server调优系列基础篇(联合运算符总结)

    前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server200 ...

  5. SQL Server调优系列基础篇(并行运算总结)

    前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...

  6. SQL Server调优系列基础篇(并行运算总结篇二)

    前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...

  7. SQL Server调优系列基础篇(索引运算总结)

    前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方 ...

  8. SQL Server调优系列基础篇(子查询运算总结)

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  9. 金三银四跳槽季,BAT美团滴滴java面试大纲(带答案版)之一:Java基础篇

    Java基础篇: 题记:本系列文章,会尽量模拟面试现场对话情景, 用口语而非书面语 ,采用问答形式来展现.另外每一个问题都附上“延伸”,这部分内容是帮助小伙伴们更深的理解一些底层细节的补充,在面试中可 ...

随机推荐

  1. mongdb 慢查询

    查看mongodb慢查询 赶紧打开服务器爸爸,开慢查询,看下耗时500ms以上的都是些啥: db.setProfilingLevel(2,500) 看下最近的10条具体的慢查询指令: db.syste ...

  2. 关于Unity的C#基础学习(三)

    面向对象 一.编码注意 1.每个C#的脚本只有唯一的一个类是继承自MonoBehaviour 2.类的名字要和我们的文件名字一样 3.代码的缩进 个人习惯:在类的内部来访问数据成员/成员函数的时候,用 ...

  3. 第二百六十五节,xss脚本攻击介绍

    xss脚本攻击介绍 Cross-Site Scripting(XSS)是一类出现在 web 应用程序上的安全弱点,攻击者可以通过 XSS 插入一 些代码,使得访问页面的其他用户都可以看到,XSS 通常 ...

  4. pychram最新注册码

    2016年的激活码只能用到2017.2.25,于昨日已经过期了. 现提供最新激活码: BIG3CLIK6F-eyJsaWNlbnNlSWQiOiJCSUczQ0xJSzZGIiwibGljZW5zZW ...

  5. 对Python线程池

    本文对Python线程池进行详细说明介绍,IDE选择及编码的解决方案进行了一番详细的描述,实为Python初学者必读的Python学习经验心得. AD: 干货来了,不要等!WOT2015 北京站演讲P ...

  6. Python零碎(一)

    Python中的__name__和__main__含义详解 在写Python代码和看Python代码时,我们常常可以看到这样的代码: def main(): ...... if __name == & ...

  7. WebApi(6) 后台C#调用WebApi

    https://www.cnblogs.com/cxd1008/p/6640015.html 今天来写一下后台C#代码如何访问webapi 这里使用HttpClient方法访问webapi也是很常用的 ...

  8. android Contacts/Acore进程常常被Kill,导致联系人开机后丢失怎么办?

    Contacts/Acore进程,在内存较少和开机进程过多的情况下会常常被 ActivityManager Kill 掉. 导致Sim卡联系人开机后未导入或者仅仅导入一部分,造成联系人丢失的现象,可是 ...

  9. php 快速读取文件夹下文件列表

    在读取某个文件夹下的内容的时候 以前是使用 opendir readdir结合while循环过滤 . ..当前文件夹和父文件夹来操作的. 代码如下: 然后偶然发现了有scandir函数 可以扫描文件夹 ...

  10. jquery做简单特效

    1.点击触发消失效果 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...