php解决浮点数计算函数bc函数不四舍五入问题(转)

原文: https://blog.csdn.net/qq_29309533/article/details/114322351

PHP浮点数计算函数不四舍五入
之前做统计模块时,遇到PHP计算精度的问题,比如:

$a = 2586;
$b = 2585.98;

var_dump(a-b);

//期望的结果是:
float(0.02)

//实际结果:
float(0.019999999999982)

之后统一换成加bcadd() 、减 bcsub() 、 乘bcmul() 、除 bcdiv()等计算方法,然后又发现第三个参数的保留小数位数是直接截取,不进行四舍五入,比如:

$a = 1186;
$b = 865;
$ab = 2051;
//两个值相加结果是2051

//然后我们来计算百分比
a_rate = bcdiv(a,$ab,3);
b_rate = bcdiv(b,$ab,3);

//$a_rate = 0.578
//$b_rate = 0.421

很明显0.578跟0.421相加不等于1,所以还得对浮点数计算的函数进行修改

/**
 * 修改bcadd方法,避免直接截取小数位不四舍五入的问题
 * @param Float $left_value 加号左边数
 * @param Float $right_value 加号右边数
 * @param Int $decimal_places 保留小数位,默认0
 * @return Float 返回结果
 */
function round_bcadd($left_value,$right_value,$decimal_places=0){
    return round(bcadd($left_value,$right_value,bcadd($decimal_places,2)),$decimal_places);
}

/**
 * 修改bcsub方法,避免直接截取小数位不四舍五入的问题
 * @param Float $left_value 减号左边数
 * @param Float $right_value 减号右边数
 * @param Int $decimal_places 保留小数位,默认0
 * @return Float 返回结果
 */
function round_bcsub($left_value,$right_value,$decimal_places=0){
    return round(bcsub($left_value,$right_value,bcadd($decimal_places,2)),$decimal_places);
}

/**
 * 修改bcmul方法,避免直接截取小数位不四舍五入的问题
 * @param Float $left_value 乘号左边数
 * @param Float $right_value 乘号右边数
 * @param Int $decimal_places 保留小数位,默认0
 * @return Float 返回结果
 */
function round_bcmul($left_value,$right_value,$decimal_places=0){
    return round(bcmul($left_value,$right_value,bcadd($decimal_places,2)),$decimal_places);
}

/**
 * 修改bcdiv方法,避免直接截取小数位不四舍五入的问题
 * @param Float $left_value 分子
 * @param Float $right_value 分母
 * @param Int $decimal_places 保留小数位,默认0
 * @return Float 返回结果
 */
function round_bcdiv($left_value,$right_value,$decimal_places=0){
    return round(bcdiv($left_value,$right_value,bcadd($decimal_places,2)),$decimal_places);
}

借助PHP的round方法,浮点数计算的时候把保留小数位多加两位,然后用round根据实际需求位数进行四舍五入,OK问题完美解决

posted @ 2022-10-09 15:02  pine007  阅读(1162)  评论(0编辑  收藏  举报