bcpow's no-fraction-exponent limitation and work around

THERE IS A NEW VERSION WHICH IS MANY TIMES FASTER, CHECK IT OUT

bcpow() can't have any non-integer as an exponent, check out this code:

echo bcpow(3, 1/3);//out put 1, also, input should be string
//but it is automatically converted from number to string
echo pow(3, 1/3);//out put 1.44224957

This is one of the worst thing could happen: Start using BC because of very mathematical reasons, and now found out one of the simplest math operation can not be done in BC!
Well, at least with the bcsqrt(), you can do at least a bit more, here are some examples:

//BCMath equivalent of pow(6, 4.5)
bcmul(bcpow(6,4),bcsqrt(6));
//BCMath equivalent of pow(6, 3.25)
bcmul(bcpow(6,3),bcsqrt(bcsqrt(6));

But what if you want a cube root of a number? that's why I start to write PHP scripts to complete BCMath, and I will call it BCExt Lib, and here are the first 2 functions which solve the bcpow problem.

function bcgetscale(){
	return strlen(bcadd(1,0))-2;
}

This will be the ultimate function to find the bcscale default. This will be used in each BCExt functions to get the scale and reset it.

//Version 0.1 of BCRoot
//To do: Optimize the speed by use as much bcsqrt as possible.
function bcroot($a, $n, $scale='default'){
	$default = bcgetscale();//Get the scale
	if($scale == 'default'){
		$scale = $default;//use default scale
	}
	if($n & ($n-1)){//check if $n is the power of 2, return 0 if is
       //now use Newton's method to find the number
		bcscale($scale+15);
		$x = 1;
		$k = 0;
		$limit = ceil(log($scale+15)/log(2))+1;
		while($k<$limit){
			$t1 = bcdiv(1,$n);
			$t21 = bcmul(bcsub($n,1),$x);
			$t22 = bcdiv($a,bcpow($x, $n-1));
			$t2 = bcadd($t21,$t22);
			$x = bcmul($t1, $t2);
			++$k;
		}
		bcscale($default);
		return bcadd($x,0,$scale);
	}else{
    //here use many bcsqrt, because this is FAST
		$i = 0;
		$pow = log($n)/log(2);
		while($i < $pow){
			$a = bcsqrt($a,$scale);
			++$i;
		}
		return $a;
	}
}

With this two functions, things like this could be possible

//BCMath + BCExt equivalent of pow(6, 2/3)
bcmul(bcpow(6,2),bcroot(6,3));

Happy Coding...


Comments

Anonymous's picture

[...] week ago, I have

[...] week ago, I have released a bcpow() no fraction exponent work around. It is good, like all my scripts, but it is not fast. This code could take 12.152509 second to run [...]

Anonymous's picture

[...] bcpow’s

[...] bcpow’s no-fraction-exponent limitation and work around [...]

Post new comment

  • Allowed HTML tags: <img> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <span> <fn>
  • Lines and paragraphs break automatically.
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Mathematical equations and graphs can be added between [tex] and [/tex], [graph] and [/graph] tags.
  • Textual smileys will be replaced with graphical ones.

More information about formatting options

Honey Pot that kill bots