开方函数手动实现

曾经面试让手动实现保留2位小数的函数,现在想来将其发出来(排版可能不好,因为csdn体验度本来就差)​​​​​​​​​​​​​​

实现思想:

利用二分法找整数,循环迭代找小数。

例如:111开方,保留两位小数。

(10+a)^2 = 111

a^2 + 2 * 10 * a = 11

a = 0.55 - a^2 / 20事实上

因为0<a<1

-0.05<-a^2/20<0

0.5<a<0.55

所以小数第一位为5

然后找第二位

(10.5+a)^2 = 111

重复第一步操作,直到找到第二位小数。

注意:这里为了获得更加精准的结果通常要多运行一位。

例如获取2为小数,实际要计算三位精度,然后再取两位小数(四舍五入)

 

// 开方
function _sqrt($targetNumber, $d){
    if($targetNumber < 0 ){
        exit('error');
    }else if($targetNumber == 0 ){
        return 0;
    }
    $ac = 1;$ack = $ac;
    for($i = 0; $i <= $d; $i++){
        $ack = $ack / 10;
    }
    $sqrtNumber = findInteger($targetNumber);
    while(1){
        if($ac == $ack) break;
        $decimal = ($targetNumber - $sqrtNumber * $sqrtNumber) / 2 / $sqrtNumber;
        $sqrtNumber = $sqrtNumber +  $decimal - $ac / 2 / $sqrtNumber;
        $ac = $ac / 10;
    }
    return sprintf("%.".$d."f", $sqrtNumber);
}

//整数
function findInteger($targetNumber){
    $sqrtNumber = $targetNumber;
    while(1){
        $sqrtNumber = floor($sqrtNumber / 2);
        $square = $sqrtNumber * $sqrtNumber;
        if($square - $targetNumber > $targetNumber){
            continue;
        }
        $remain = $square - $targetNumber;
        $sqrtNumber = $sqrtNumber - floor($remain / 2 / $sqrtNumber);
        while(1){
            if($sqrtNumber * $sqrtNumber < $targetNumber) break;
            $sqrtNumber--;
        }
        break;
    }
    return $sqrtNumber;
}
$number = '216';
echo _sqrt($number,2);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值