More sophisticated parser... in time, I'll factor complex functions out from the engineering functions class, and use this as the basis for that rework

git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@86199 2327b42d-5241-43d6-9e2a-de5ac946f064
This commit is contained in:
Mark Baker 2012-02-08 21:39:02 +00:00
parent 73f013c68f
commit 897d8843c4

View File

@ -4,40 +4,74 @@ class Complex {
private $realPart = 0; private $realPart = 0;
private $imaginaryPart = 0; private $imaginaryPart = 0;
private $suffix = 'i'; private $suffix = NULL;
public static function _parseComplex($complexNumber) { public static function _parseComplex($complexNumber)
$complexNumber = (string) $complexNumber; {
// Test for real number, with no imaginary part
if (is_numeric($complexNumber))
return array( $complexNumber, 0, NULL );
// Fix silly human errors
if (strpos($complexNumber,'+-') !== FALSE)
$complexNumber = str_replace('+-','-',$complexNumber);
if (strpos($complexNumber,'--') !== FALSE)
$complexNumber = str_replace('--','-',$complexNumber);
// Basic validation of string, to parse out real and imaginary parts, and any suffix
$validComplex = preg_match('/^([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-2]?\d{1,2})?)([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-2]?\d{1,2})?)?(([-+]?)([ij]?))$/ui',$complexNumber,$complexParts); $validComplex = preg_match('/^([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-2]?\d{1,2})?)([-+]?(\d+\.?\d*|\d*\.?\d+)([Ee][-+]?[0-2]?\d{1,2})?)?(([-+]?)([ij]?))$/ui',$complexNumber,$complexParts);
if (!$validComplex) { if (!$validComplex) {
return array( $complexNumber, 0, '' ); // Neither real nor imaginary part, so test to see if we actually have a suffix
$validComplex = preg_match('/^([-+]?)([ij])$/ui',$complexNumber,$complexParts);
if (!$validComplex) {
throw new Exception('COMPLEX: Invalid complex number');
}
// We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)
$imaginary = 1;
if ($complexParts[1] === '-') {
$imaginary = 0 - $imaginary;
}
return array(0, $imaginary, $complexParts[2]);
} }
// If we don't have an imaginary part, identify whether it should be +1 or -1...
if (($complexParts[4] === '') && ($complexParts[9] !== '')) { if (($complexParts[4] === '') && ($complexParts[9] !== '')) {
$complexParts[4] = $complexParts[8] . 1; if ($complexParts[7] !== $complexParts[9]) {
$complexParts[4] = 1;
if ($complexParts[8] === '-') {
$complexParts[4] = -1;
}
// ... or if we have only the real and no imaginary part (in which case our real should be the imaginary)
} else {
$complexParts[4] = $complexParts[1];
$complexParts[1] = 0;
}
} }
return array( (float) $complexParts[1], // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily
(float) $complexParts[4], return array( $complexParts[1],
$complexParts[9] $complexParts[4],
!empty($complexParts[9]) ? $complexParts[9] : 'i'
); );
} // function _parseComplex() } // function _parseComplex()
public function __construct($realPart, $imaginaryPart = null, $suffix = null) public function __construct($realPart, $imaginaryPart = null, $suffix = 'i')
{ {
if ($imaginaryPart === null) { if ($imaginaryPart === null) {
if (is_array($realPart)) { if (is_array($realPart)) {
list ($realPart, $imaginaryPart, $suffix) = $realPart; // We have an array of (potentially) real and imaginary parts, and any suffix
list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i');
} elseif((is_string($realPart)) || (is_numeric($realPart))) { } elseif((is_string($realPart)) || (is_numeric($realPart))) {
// We've been given a string to parse to extract the real and imaginary parts, and any suffix
list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart); list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart);
} }
} }
$this->realPart = $realPart; // Set parsed values in our properties
$this->imaginaryPart = $imaginaryPart; $this->realPart = (float) $realPart;
$this->imaginaryPart = (float) $imaginaryPart;
$this->suffix = strtolower($suffix); $this->suffix = strtolower($suffix);
} }
@ -58,12 +92,20 @@ class Complex {
public function __toString() { public function __toString() {
$str = ""; $str = "";
if ($this->imaginaryPart != 0.0) $str .= $this->imaginaryPart . $this->suffix; if ($this->imaginaryPart != 0.0) {
if (abs($this->imaginaryPart) != 1.0) {
$str .= $this->imaginaryPart . $this->suffix;
} else {
$str .= (($this->imaginaryPart < 0.0) ? '-' : ''). $this->suffix;
}
}
if ($this->realPart != 0.0) { if ($this->realPart != 0.0) {
if ($str) $str = "+" . $str; if (($str) && ($this->imaginaryPart > 0.0))
$str = "+" . $str;
$str = $this->realPart . $str; $str = $this->realPart . $str;
} }
if (!$str) $str = "0"; if (!$str)
$str = "0.0";
return $str; return $str;
} }