1function bcroot($幂, $指 = '3', $scale = 0){ 2 #开方 3 $d = false; 4 if($幂 == '0'){ 5 return '0'; 6 }elseif($幂 == '1'){ 7 return '1'; 8 } 9 10 $指数 = intval($指); 11 $底扩位数 = $scale; 12 $幂扩位数 = $指数 * $底扩位数; 13 14 $幂 = bcmul($幂,str_pad('1',$幂扩位数+1,'0')); 15 16 $小数点位 = strpos($幂,'.'); 17 if($小数点位 !== FALSE){ 18 $幂 = substr($幂,0,$小数点位); 19 } 20 21 $幂长 = strlen($幂); 22 $底数长 = ceil($幂长 / $指数); 23 24 #初次逆序 25 $幂 = strrev($幂); 26 $幂段 = array_reverse(str_split($幂,$指数)); 27 $底数 = ''; 28 $小余 = '0'; 29 foreach($幂段 as $小幂){ 30 #再次逆序,则正过来 31 $小幂 = strrev($小幂); 32 33 # (底 . 小底)^指数 - 小底^指数 <= 小余 . 小幂 34 35 if($小余 != '0'){ 36 $此幂 = $小余.$小幂; 37 }else{ 38 $此幂 = $小幂; 39 } 40 41 $小余 = '0'; 42 43 $小底 = '1'; 44 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 45 $比较 = bccomp(${'试幂'.$小底},$此幂); 46 if($比较 == '1'){ 47 # x<1 48 $小底 = '0'; 49 $小余 = $此幂; 50 }else{ 51 # 1<x 52 $小底 = '9'; 53 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 54 $比较 = bccomp(${'试幂'.$小底},$此幂); 55 if($比较 == '-1'){ 56 # 9<x 57 $小底 = '9'; 58 $小余 = bcsub($此幂,${'试幂'.$小底}); 59 }else{ 60 # 1<x<9 61 $小底 = '5'; 62 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 63 $比较 = bccomp(${'试幂'.$小底},$此幂); 64 if($比较 == '1'){ 65 # 1<x<5 66 $小底 = '3'; 67 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 68 $比较 = bccomp(${'试幂'.$小底},$此幂); 69 if($比较 == '1'){ 70 # 1<x<3 71 $小底 = '2'; 72 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 73 $比较 = bccomp(${'试幂'.$小底},$此幂); 74 if($比较 == '1'){ 75 # 1<x<2 76 $小底 = '1'; 77 $小余 = bcsub($此幂,${'试幂'.$小底}); 78 }else{ 79 # 2<x<3 80 $小底 = '2'; 81 $小余 = bcsub($此幂,${'试幂'.$小底}); 82 } 83 }else{ 84 # 3<x<5 85 $小底 = '4'; 86 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 87 $比较 = bccomp(${'试幂'.$小底},$此幂); 88 if($比较 == '1'){ 89 # 3<x<4 90 $小底 = '3'; 91 $小余 = bcsub($此幂,${'试幂'.$小底}); 92 }else{ 93 # 4<x<5 94 $小底 = '4'; 95 $小余 = bcsub($此幂,${'试幂'.$小底}); 96 } 97 } 98 }else{ 99 # 5<x<9 100 $小底 = '7'; 101 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 102 $比较 = bccomp(${'试幂'.$小底},$此幂); 103 if($比较 == '1'){ 104 # 5<x<7 105 $小底 = '6'; 106 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 107 $比较 = bccomp(${'试幂'.$小底},$此幂); 108 if($比较 == '1'){ 109 # 5<x<6 110 $小底 = '5'; 111 $小余 = bcsub($此幂,${'试幂'.$小底}); 112 }else{ 113 # 6<x<7 114 $小底 = '6'; 115 $小余 = bcsub($此幂,${'试幂'.$小底}); 116 } 117 }else{ 118 # 7<x<9 119 $小底 = '8'; 120 ${'试幂'.$小底} = bcpow_sub($底数,$小底,$指); 121 $比较 = bccomp(${'试幂'.$小底},$此幂); 122 if($比较 == '1'){ 123 # 7<x<8 124 $小底 = '7'; 125 $小余 = bcsub($此幂,${'试幂'.$小底}); 126 }else{ 127 # 8<x<9 128 $小底 = '8'; 129 $小余 = bcsub($此幂,${'试幂'.$小底}); 130 } 131 } 132 } 133 } 134 } 135 $底数 .= $小底; 136 } 137 138 $底数 = bcdiv($底数,str_pad('1',$底扩位数+1,'0'),$scale); 139 return $底数; 140} 141 142function bcpow_sub($底,$小底,$指){ 143 if($底 == '0' or $底 == ''){ 144 return bcpow($小底,$指); 145 }else{ 146 return bcsub(bcpow($底 . $小底,$指),bcpow($底 .'0',$指)); 147 } 148}
BC开方(乙)
Wesley13
2021-10-11
1055 0 0
点赞
收藏
评论区
加载中...