通用类,拿走不谢
<?php
/**
* 浮点数计算函数封装compare
* User: [email protected]
* Date: 2018/8/8
* Time: 下午3:12
*/
namespace leyangjun\Lib;
class Bc
{
// 金额计算方式, 增加
const CALC_ADD = 'add';
// 金额计算方式, 减少
const CALC_SUB = 'sub';
// 金额计算方式, 相除
const CALC_DIV = 'div';
// 金额计算方式, 相乘
const CALC_MUL = 'mul';
// 金额计算方式, 比较大小
const CALC_COMP = 'comp';
/**
* 使用较高精度的计算方法
* @param $amount_1
* @param $amount_2
* @param $precision
* @param string $method
* @return float|int|string
*/
public function calculateByPrecision($amount_1, $amount_2, $precision, $method = self::CALC_ADD)
{
$amount = 0;
// 如果为金额小于0且为加法, 则自动转化为减法
if ($method == self::CALC_ADD && $amount_2 < 0) {
$method = self::CALC_SUB;
}
$bc_exists = function_exists('bcadd');
switch ($method) {
case self::CALC_ADD :
$amount = $bc_exists ? bcadd($amount_1, $amount_2, $precision) : round($amount_1 + $amount_2, $precision);
break;
case self::CALC_SUB :
$amount = $bc_exists ? bcsub($amount_1, abs($amount_2), $precision) : round($amount_1 - abs($amount_2), $precision);
break;
case self::CALC_DIV :
$amount = $bc_exists ? bcdiv($amount_1, $amount_2, $precision) : round($amount_1 / $amount_2, $precision);
break;
case self::CALC_MUL :
$amount = $bc_exists ? bcmul($amount_1, $amount_2, $precision) : round($amount_1 * $amount_2, $precision);
break;
case self::CALC_COMP :
// 高精度的比较, 返回1表示 $amount_1 > $amount_2
$amount = $bc_exists ? bccomp($amount_1, $amount_2, $precision) : ($amount_1 > $amount_2 ? 1 : ($amount_1 == $amount_2 ? 0 : -1));
break;
}
return $amount;
}
/**
* 检测第一个数是否大于第二个数
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return boolean
*/
public function isGt($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_COMP) === 1;
}
/**
* 检测第一个数是否大于等于第二个数
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return boolean
*/
public function isGe($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_COMP) !== -1;
}
/**
* 检测两个数是否相等
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return boolean
*/
public function isEqual($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_COMP) === 0;
}
/**
* 检测$amount_1是否在$amount_2和$amount_3这个区间
* @param $amount_1
* @param $amount_2
* @param $amount_3
* @param int $precision
* @param boolean $is_contain_critical 是否包含$amount_2和$amount_3临界点
* @return boolean
*/
public function isInInterval($amount_1, $amount_2, $amount_3, $precision = 2, $is_contain_critical = true)
{
if ($is_contain_critical) {
if (!$this->isGe($amount_1, $amount_2, $precision)) {
return false;
}
if ($this->isGt($amount_1, $amount_3, $precision)) {
return false;
}
return true;
}
// 不包含临界点
if (!$this->isGt($amount_1, $amount_2, $precision)) {
return false;
}
if ($this->isGe($amount_1, $amount_3, $precision)) {
return false;
}
return true;
}
/**
* 两个数相加
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return float
*/
public function calcAdd($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_ADD);
}
/**
* 对数组中所有数值进行求和
*/
public function calcAddArray(array $arr, $precision = 2)
{
$sum = '0.00';
foreach ($arr as $val) {
if ( is_numeric($val) ) {
$sum = $this->calcAdd($sum, $val, $precision);
}
}
return $sum;
}
/**
* 两个数相减
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return float
*/
public function calcSub($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_SUB);
}
/**
* 两个数相乘
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return float
*/
public function calcMul($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_MUL);
}
/**
* 两个数相除
* @param float $amount_1
* @param float $amount_2
* @param int $precision
* @return float
*/
public function calcDiv($amount_1, $amount_2, $precision = 2)
{
return $this->calculateByPrecision($amount_1, $amount_2, $precision, self::CALC_DIV);
}
}
PHP浮点数计算函数统一封装
猜你喜欢
转载自blog.csdn.net/leyangjun/article/details/81509215
今日推荐
周排行