Hi,
habe gerade für ein paar Berechnungen im Bereich Arithmetic Coding eine kleine BCNumber-Klasse geschrieben, die die BC-Funktionalitäten [1] von PHP etwas objekt-orientiert kapselt.
Aufgerufen werden können alle in __call() vermerkten "bc"-Prefix-Funktionen:
"add", "comp", "div", "mod", "mul", "pow", "powmod", "sqrt", "sub"
PHP-Code:
<?php
class BCNumber
{
/**
* default scale (rounding)
* @const integer
*/
const SCALE_DEFAULT = 100;
/**
* number value
* @var string
*/
protected $_number = NULL;
/**
* flag to remember previously executed auto-scaling
* @staticvar bool already auto-scaled
*/
protected static $_scaled = NULL;
/**
* overgive string number
* @param string $number
*/
public function __construct($number)
{
// auto-scale (static property)
if (is_null(self::$_scaled)) {
self::scale();
}
$this->_number = (string)$number;
}
/**
* magic method, string-conversion
* @return string number
*/
public function __toString()
{
return $this->_number;
}
/**
* magic method, allows the specified ($method) functions to be called as method
* method name will be prefixed with "bc", to call the binary calculator functions
* you are allowed to call that functinos with a prefixed "r" to return the value instead of saving it
*
* @see BCNumber::scale()
* @warning it's a magic method, you'll never call that method with this name
* @example
* <code>
* $bcnumber = new BCNumber("1");
* $bcnumber->div(new BCNumber("3")); // $bcnumber->_number is now 0.3333 ..
*
* $bcnumber = new BCNumber("1");
* echo $bcnumber->rdiv(new BCNumber("3")); // output will be 0.3333 ..
* </code>
*/
public function __call($method, $params)
{
$function = NULL;
$return = FALSE;
$methods = array("add", "comp", "div", "mod", "mul", "pow", "powmod", "sqrt", "sub"); // no scale, see below
if (in_array($method, $methods)) {
$function = "bc" . $method;
}
if (strpos($method, "r") === 0 && in_array(substr($method, 1), $methods)) {
$function = "bc" . substr($method, 1);
$return = TRUE;
}
if (is_null($function) || !function_exists($function)) {
throw new Exception("unexpected method ($method) called");
}
array_unshift($params, $this->_number);
$result = call_user_func_array($function, $params);
if ($return) {
return new BCNumber($result);
}
$this->_number = $result;
}
/**
* This method will be called automatically by the first object instance of BCNumber, if you did not call it
* by yourself before.
*
* @warning it's a static method setting a global option, so its scope is (guess?) global
* @param int $scale
*/
public static function scale($scale = self::SCALE_DEFAULT)
{
return self::$_scaled = bcscale($scale);
}
}
?>
Aufrufe der Funktionen sind auf zwei verschiedenen Wegen möglich:
mit Prefix-"r" (steht für
return) oder ohne.
PHP-Code:
<?php
// speichert das Ergebnis im Zustand:
$a = new BCNumber("9652654343754337936539563963573957");
$b = new BCNumber("9537595865211239537");
$a->div($b);
// liefert das Ergebnis nur als Rückgabewert:
$c = $a->rdiv($b);
?>
Vielleicht brauchs mal wer ..
[1]
http://de.php.net/manual/en/ref.bc.php