function bcroot($冪, $指 = '3', $scale = 0){ #開方 $d = false; if($冪 == '0'){ return '0'; }elseif($冪 == '1'){ return '1'; } $指數 = intval($指); $底擴位數 = $scale; $冪擴位數 = $指數 * $底擴位數; $冪 = bcmul($冪,str_pad('1',$冪擴位數+1,'0')); $小數點位 = strpos($冪,'.'); if($小數點位 !== FALSE){ $冪 = substr($冪,0,$小數點位); } $冪長 = strlen($冪); $底數長 = ceil($冪長 / $指數); #初次逆序 $冪 = strrev($冪); $冪段 = array_reverse(str_split($冪,$指數)); $底數 = ''; $小余 = '0'; foreach($冪段 as $小冪){ #再次逆序,則正過來 $小冪 = strrev($小冪); # (底 . 小底)^指數 - 小底^指數 <= 小余 . 小冪 if($小余 != '0'){ $此冪 = $小余.$小冪; }else{ $此冪 = $小冪; } $小余 = '0'; $小底 = '1'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # x<1 $小底 = '0'; $小余 = $此冪; }else{ # 1<x $小底 = '9'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '-1'){ # 9<x $小底 = '9'; $小余 = bcsub($此冪,${'試冪'.$小底}); }else{ # 1<x<9 $小底 = '5'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 1<x<5 $小底 = '3'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 1<x<3 $小底 = '2'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 1<x<2 $小底 = '1'; $小余 = bcsub($此冪,${'試冪'.$小底}); }else{ # 2<x<3 $小底 = '2'; $小余 = bcsub($此冪,${'試冪'.$小底}); } }else{ # 3<x<5 $小底 = '4'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 3<x<4 $小底 = '3'; $小余 = bcsub($此冪,${'試冪'.$小底}); }else{ # 4<x<5 $小底 = '4'; $小余 = bcsub($此冪,${'試冪'.$小底}); } } }else{ # 5<x<9 $小底 = '7'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 5<x<7 $小底 = '6'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 5<x<6 $小底 = '5'; $小余 = bcsub($此冪,${'試冪'.$小底}); }else{ # 6<x<7 $小底 = '6'; $小余 = bcsub($此冪,${'試冪'.$小底}); } }else{ # 7<x<9 $小底 = '8'; ${'試冪'.$小底} = bcpow_sub($底數,$小底,$指); $比較 = bccomp(${'試冪'.$小底},$此冪); if($比較 == '1'){ # 7<x<8 $小底 = '7'; $小余 = bcsub($此冪,${'試冪'.$小底}); }else{ # 8<x<9 $小底 = '8'; $小余 = bcsub($此冪,${'試冪'.$小底}); } } } } } $底數 .= $小底; } $底數 = bcdiv($底數,str_pad('1',$底擴位數+1,'0'),$scale); return $底數; } function bcpow_sub($底,$小底,$指){ if($底 == '0' or $底 == ''){ return bcpow($小底,$指); }else{ return bcsub(bcpow($底 . $小底,$指),bcpow($底 .'0',$指)); } }