php浮点数精确运算之bc系列函数

bc是Binary Calculator的缩写。bc*函数的参数都是操作数加上一个可选的 [int scale],比如string bcadd(string $left_operand, string $right_operand[, int $scale]),如果scale没有提供,就用bcscale的缺省值。这里大数直接用一个由0-9组成的string表示,计算结果返回的也是一个 string。

 1 bcadd — 将两个高精度数字相加
 2 bccomp — 比较两个高精度数字,返回-1, 0, 1
 3 bcdiv — 将两个高精度数字相除
 4 bcmod — 求高精度数字余数
 5 bcmul — 将两个高精度数字相乘
 6 bcpow — 求高精度数字乘方
 7 bcpowmod — 求高精度数字乘方求模,数论里非常常用
 8 bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=”
 9 bcsqrt — 求高精度数字平方根
10 bcsub — 将两个高精度数字相减

首先看一段代码:

1 <?php
2 $a = 0.1;
3 $b = 0.7;
4 var_dump(($a + $b) == 0.8);

打印出来的值居然为 boolean false

这是为啥?PHP手册对于浮点数有以下警告信息:

Warning 
浮点数精度
显然简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999...。 
这和一个事实有关,那就是不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333. . .。 
所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数

那么上面的算式我们应该改写为

1 <?php
2 $a = 0.1;
3 $b = 0.7;
4 var_dump(bcadd($a,$b,2) == 0.8);

这样就能解决浮点数的计算问题了。

时间: 2024-10-10 22:21:51

php浮点数精确运算之bc系列函数的相关文章

JS/PHP 浮点数精确运算

php浮点数精确运算 bc是Binary Calculator的缩写.bc*函数的参数都是操作数加上一个可选的 [int scale],比如string bcadd(string $left_operand, string $right_operand[, int $scale]),如果scale没有提供,就用bcscale的缺省值.这里大数直接用一个由0-9组成的string表示,计算结果返回的也是一个 string. bcadd — 将两个高精度数字相加bccomp — 比较两个高精度数字,

php浮点数精确运算

bc是Binary Calculator的缩写.bc*函数的參数都是操作数加上一个可选的 [int scale],比方string bcadd(string $left_operand, string $right_operand[, int $scale]),假设scale没有提供,就用bcscale的缺省值.这里大数直接用一个由0-9组成的string表示,计算结果返回的也是一个 string. bcadd - 将两个高精度数字相加 bccomp - 比較两个高精度数字,返回-1, 0, 1

Linux上整数和浮点数的运算

一:shell中对整数和浮点数的运算 常用的运算符号 加法+    减法 -     乘法*     除法/     求余% +=        -=        *=       /=        %= 1.整数的运算 (1).使用expr命令(注意:要求操作数和操作数之间用空格隔开,否则只会打印字符串) expr 1 + 1 expr 2 - 1 expr 2 \* 2 expr 2 / 1 expr 1 % 6 例如执行:#! /bin/bash num=$(expr 1 + 1) e

由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入

public class Arith { /** * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入. */ // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10; // 这个类不能实例化 private Arith() { } /** * 提供精确的加法运算. * * @param v1 * 被加数 * @param v2 * 加数 * @return 两个参数的和 */ p

整数和浮点数及运算函数

整数有4种进制表示形式: 十进制 二进制,以0b或0B开头 八进制,以0o或0O开头 十六进制,以0x或0X开头 浮点数 浮点数之间运算存在不确定尾数,不是bug 0.1+0.2=0.30000000000000004 所以浮点数间运算与比较用round()函数来辅助 round(x, d):对x四舍五入,d是保留的小数位数 round(0.1+0.2, 1)==0.3返回True 不过要注意round的一些限制,具体可以参考这个链接: Python 中关于 round 函数的小坑 浮点数科学计

GCC自带位运算系列函数

谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error "-std=c++11"//C++11 然而又有多少人知道__builtin_xxx()这群神奇的存在? 举个栗子:树状数组的核心思想就是一个叫做lowbit()的函数,它是这样写的: inline int lowbit(const int &x) { return x & -x; } 什么,你说长

JavaScript 浮点数及运算精度调整总结

JavaScript 浮点数及运算精度调整总结 JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的. 作者:来源:theWalker|2015-12-02 10:21 移动端 收藏 分享 [技术沙龙]AI开发者实战营-7分钟打造1个定制技能.7月22号,我们等你一起! JavaScript 只有一种数字类型 Number,而且在Jav

openssl之EVP系列之10---EVP_Sign系列函数介绍

---依据openssl doc/crypto/EVP_SignInit.pod翻译 (作者:DragonKing, Mail: [email protected] ,公布于:http://openssl.126.com 之openssl专业论坛,版本号:openssl-0.9.7) EVP_Sign系列函数使用的基础结构跟信息摘要算法使用的基础结构是一样的.并且,其前面的两个操作步骤初始化和数据操作(信息摘要)也跟信息摘要算法是一样的,唯一不一样的是最后一步操作.本系列函数做了签名的工作,而信

[OS] 多线程--原子操作 Interlocked系列函数

转自:http://blog.csdn.net/morewindows/article/details/7429155 上一篇<多线程--第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将一个表示计数的变量递增.程序在最后输出计数的值表示有今天多少个用户登录,如果这个值不等