Archive - Jan 19, 2007

Date

BCMath is crazy, that's why I have tips

BCMath is very useful when the most important data have to be exact. I started to use BCMath to write a high precision pi library. When a programmer is using BCMath, he will find he have to input the very crazy equations into code, and sometimes, it won't work first time. For example:
atan equation
Well, let's forget about the Sigma, just the things behind the sigma. This equation is pretty hard to be written into BCMath formation on the fly.

That's why, break everything apart, make there is only one BCMath function per round, like this:

$top = pow(-1, $n+1);
$bot = $n * 2 - 1;
$times = bcpow($x, $n * 2 -1, 30);
$frac = bcdiv($top, $bot, 30);
$mul = bcmul($frac, $times, 30);

Humm, why do we have to put the third parameter for each BCMath function to specify precision? if it is all the same, we can just use bcscale() and finish the job.
Now, run the code and check if it works. If it does, condense the code into one line by substitute the variables with equations. Why? it speed the script up because there will be less variable creating and destroying(unless one calculated value is repeated used many times). here is the result.

bcscale(30);
$return = bcmul(bcdiv(pow(-1, $n+1), $n * 2 - 1), bcpow($x, $n * 2 -1));

There are some numbers inside the equation that does not use the BCMath functions, the reason is simple, there is no point. If you know a number will come out as a integer or as a reasonable decimal(like, 1/5), don't use the fairly slow BCMath.

PHP: Calculate PI

Note: Newer version of the pi calculation is here and a even more faster one here.
I want to release some Benchmark system can be uploaded to any web host and check how good the web hosting is. Pi (?) calculations spread widely as one of the most popular CPU benchmark system, that's why I have created a Pi calculator that can get to the accuracy you want. For now, there is still one thing I'm not sure yet, I will explain it after show you the code.

function bcpi($precision=30){
        $accuracy = ($precision+5)*45/32;
//accuracy worked till the 180th $precision, almost used 30 second to calculate
	bcscale($precision+5);
	$n = 1;
	$bcatan1 = 0;
	$bcatan2 = 0;
	while($n < $accuracy){
//atan functions
		$bcatan1 = bcadd($bcatan1, bcmul(bcdiv(pow(-1, $n+1), $n * 2 - 1), bcpow(0.2, $n * 2 -1)));
		$bcatan2 = bcadd($bcatan2, bcmul(bcdiv(pow(-1, $n+1), $n * 2 - 1), bcpow(bcdiv(1,239), $n * 2 -1)));
		++$n;
	}
	return	bcmul(4,bcsub(bcmul(4, $bcatan1),$bcatan2),5);
}

This Pi formula is not the fastest(converge speed), but it is one of the easiest. it uses Machin's formula + Taylor Series work together.

So, this is the BCMath version of atan() and pi() .
Why not use the original pi()? because from the statement of Keamos at gmail on 13-Jan-2006 09:31, it shows pi() have a precision limit. Note this script is very slow, and the time it need is increase squarely, so 100 precision could use up to 1 second.

Now, I have only one problem, the Pi's accuracy, Pi's accuracy are not the same as it's precision. Precision is the number of decimal it returns, the accuracy is the closeness to the real pi's value rounded the same precision. I want to output any precision with 100% accuracy, then I must find the relationship between two of them. You guessed it right, I don't know :aok:
Edit: it looks like precision:accuracy is somewhere around 45:32.
Just Added on 2007-01-20: cut off the last few numbers because it usually not 100% accurate
If anything know something about that, please tell me about it. Thanks in advance.

PHP implementation of Pancake sort

PHP implementation of Pancake sort, the very mathy but slow(at least in PHP) sort.

function pancake_sort($array){
	$count = count($array);
	$powercount = $count - 1;
	$i = 0;
	while($i < $powercount){
		$n = 0;
		$largest = 0;
		while($n < $count){
			if($array[$largest]<$array[$n]){
				$largest = $n;
			}
			++$n;
		}
		$num = $largest/2;
		$j = 0;
		while($j < $num){
			$z = $array[$largest-$j];
			$array[$largest-$j] = $array[$j];
			$array[$j] = $z;
			++$j;
 
		}
		$num = --$count/2;
		$j = 0;
		while($j<$num){
			$z = $array[$count-$j];
			$array[$count-$j] = $array[$j];
			$array[$j] = $z;
			++$j;
		}
		++$i;
	}
	return $array;
}
Honey Pot that kill bots