Archive - Jan 24, 2007

Date

Morse Code in PHP

I just got some time and wrote a Morse code encoding and decoding system in PHP. Download it because wordpress might filter out some things.
Here is the encoder:
Download the Morse code en/decoder here!

Does your host give you the functions you need?

I doubt it. I have used many hosting and some of them don't have some useful functions, like scandir().
So I developed a way to check the difference between the host and another(usually your home machine) with the get_defined_functions(). Sometimes you will know why something works in one server and not the other.
First, run this script on your own computer

$home = get_defined_functions();
file_put_contents('data.txt',serialize($home['internal']));

Now, copy the data.txt to your host, and run this script, which must be in the same directory as data.txt.

$homefuncs = unserialize(file_get_contents ('data.txt'));
$hostfuncs = get_defined_functions();
$no = array_diff($homefuncs,$hostfuncs['internal']);
echo "<br />Functions that missed from the host:<br />";
foreach($no as $var){
	echo '<a href="http://www.php.net/',$var,'">',$var,'</a><br />';
}

This technique can also be used to check out the extensions of the server, substitute with the get_loaded_extensions(). This script can be even better if you can use get_extension_funcs() so all the function missing from the host can be categorized.

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...

Even more pi

NOTE: BELIEVE IT! A EVEN FASTER Pi CALCULATOR THAN THIS ONE IS HERE!

After last release, I found Gauss-Legendre algorithm, in theory, the higher precision pi is, the faster this algorithm will be, because each time it loop though, it will create 2 times more correct digit. Compare to the old one, the new one can beat it's speed at around 500 digits. It generates 2000 digit in 8 seconds. If I can find anything faster(which is quite possible), it should be Borwein's algorithm that have Nonic convergence. I will try to implement it into PHP soon.
So this is the result of comparing the new Gauss-Legendre pi calculator and the old one:
Pi algorithms

function bcpi($precision){
	$limit = ceil(log($precision)/log(2))-1;
	bcscale($precision+6);
	$a = 1;
	$b = bcdiv(1,bcsqrt(2));
	$t = 1/4;
	$p = 1;
	while($n < $limit){
		$x = bcdiv(bcadd($a,$b),2);
		$y = bcsqrt(bcmul($a, $b));
		$t = bcsub($t, bcmul($p,bcpow(bcsub($a,$x),2)));
		$a = $x;
		$b = $y;
		$p = bcmul(2,$p);
		++$n;
	}
	return bcdiv(bcpow(bcadd($a, $b),2),bcmul(4,$t),$precision);
}

NOTE: BELIEVE IT! A EVEN FASTER Pi CALCULATOR THAN THIS ONE IS HERE!

Honey Pot that kill bots