| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241 | <?php/** * PHPExcel * * Copyright (c) 2006 - 2011 PHPExcel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * @category	PHPExcel * @package		PHPExcel_Calculation * @copyright	Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL * @version		1.7.6, 2011-02-27 *//** PHPExcel root directory */if (!defined('PHPEXCEL_ROOT')) {	/**	 * @ignore	 */	define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');	require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');}/** * PHPExcel_Calculation_MathTrig * * @category	PHPExcel * @package		PHPExcel_Calculation * @copyright	Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel) */class PHPExcel_Calculation_MathTrig {	//	//	Private method to return an array of the factors of the input value	//	private static function _factors($value) {		$startVal = floor(sqrt($value));		$factorArray = array();		for ($i = $startVal; $i > 1; --$i) {			if (($value % $i) == 0) {				$factorArray = array_merge($factorArray,self::_factors($value / $i));				$factorArray = array_merge($factorArray,self::_factors($i));				if ($i <= sqrt($value)) {					break;				}			}		}		if (count($factorArray) > 0) {			rsort($factorArray);			return $factorArray;		} else {			return array((integer) $value);		}	}	//	function _factors()	private static function _romanCut($num, $n) {		return ($num - ($num % $n ) ) / $n;	}	//	function _romanCut()	/**	 *	ATAN2	 *	 *	This function calculates the arc tangent of the two variables x and y. It is similar to	 *		calculating the arc tangent of y ÷ x, except that the signs of both arguments are used	 *		to determine the quadrant of the result.	 *	The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a	 *		point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between	 *		-pi and pi, excluding -pi.	 *	 *	Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard	 *		PHP atan2() function, so we need to reverse them here before calling the PHP atan() function.	 *	 *	Excel Function:	 *		ATAN2(xCoordinate,yCoordinate)	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	float	$xCoordinate		The x-coordinate of the point.	 *	@param	float	$yCoordinate		The y-coordinate of the point.	 *	@return	float	The inverse tangent of the specified x- and y-coordinates.	 */	public static function ATAN2($xCoordinate, $yCoordinate) {		$xCoordinate	= (float) PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate);		$yCoordinate	= (float) PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate);		if (($xCoordinate == 0) && ($yCoordinate == 0)) {			return PHPExcel_Calculation_Functions::DIV0();		}		return atan2($yCoordinate, $xCoordinate);	}	//	function REVERSE_ATAN2()	/**	 *	CEILING	 *	 *	Returns number rounded up, away from zero, to the nearest multiple of significance.	 *	 *	@param	float	$number			Number to round	 *	@param	float	$significance	Significance	 *	@return	float	Rounded Number	 */	public static function CEILING($number,$significance=null) {		$number			= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$significance	= PHPExcel_Calculation_Functions::flattenSingleValue($significance);		if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) {			$significance = $number/abs($number);		}		if ((is_numeric($number)) && (is_numeric($significance))) {			if (self::SIGN($number) == self::SIGN($significance)) {				if ($significance == 0.0) {					return 0;				}				return ceil($number / $significance) * $significance;			} else {				return PHPExcel_Calculation_Functions::NaN();			}		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function CEILING()	/**	 *	COMBIN	 *	 *	Returns the number of combinations for a given number of items. Use COMBIN to	 *	determine the total possible number of groups for a given number of items.	 *	 *	@param	int		$numObjs	Number of different objects	 *	@param	int		$numInSet	Number of objects in each combination	 *	@return	int		Number of combinations	 */	public static function COMBIN($numObjs,$numInSet) {		$numObjs	= PHPExcel_Calculation_Functions::flattenSingleValue($numObjs);		$numInSet	= PHPExcel_Calculation_Functions::flattenSingleValue($numInSet);		if ((is_numeric($numObjs)) && (is_numeric($numInSet))) {			if ($numObjs < $numInSet) {				return PHPExcel_Calculation_Functions::NaN();			} elseif ($numInSet < 0) {				return PHPExcel_Calculation_Functions::NaN();			}			return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet);		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function COMBIN()	/**	 *	EVEN	 *	 *	Returns number rounded up to the nearest even integer.	 *	 *	@param	float	$number			Number to round	 *	@return	int		Rounded Number	 */	public static function EVEN($number) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		if (is_null($number)) {			return 0;		} elseif (is_numeric($number)) {			$significance = 2 * self::SIGN($number);			return (int) self::CEILING($number,$significance);		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function EVEN()	/**	 *	FACT	 *	 *	Returns the factorial of a number.	 *	 *	@param	float	$factVal	Factorial Value	 *	@return	int		Factorial	 */	public static function FACT($factVal) {		$factVal	= PHPExcel_Calculation_Functions::flattenSingleValue($factVal);		if (is_numeric($factVal)) {			if ($factVal < 0) {				return PHPExcel_Calculation_Functions::NaN();			}			$factLoop = floor($factVal);			if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {				if ($factVal > $factLoop) {					return PHPExcel_Calculation_Functions::NaN();				}			}			$factorial = 1;			while ($factLoop > 1) {				$factorial *= $factLoop--;			}			return $factorial ;		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function FACT()	/**	 *	FACTDOUBLE	 *	 *	Returns the double factorial of a number.	 *	 *	@param	float	$factVal	Factorial Value	 *	@return	int		Double Factorial	 */	public static function FACTDOUBLE($factVal) {		$factLoop	= floor(PHPExcel_Calculation_Functions::flattenSingleValue($factVal));		if (is_numeric($factLoop)) {			if ($factVal < 0) {				return PHPExcel_Calculation_Functions::NaN();			}			$factorial = 1;			while ($factLoop > 1) {				$factorial *= $factLoop--;				--$factLoop;			}			return $factorial ;		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function FACTDOUBLE()	/**	 *	FLOOR	 *	 *	Rounds number down, toward zero, to the nearest multiple of significance.	 *	 *	@param	float	$number			Number to round	 *	@param	float	$significance	Significance	 *	@return	float	Rounded Number	 */	public static function FLOOR($number,$significance=null) {		$number			= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$significance	= PHPExcel_Calculation_Functions::flattenSingleValue($significance);		if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) {			$significance = $number/abs($number);		}		if ((is_numeric($number)) && (is_numeric($significance))) {			if ((float) $significance == 0.0) {				return PHPExcel_Calculation_Functions::DIV0();			}			if (self::SIGN($number) == self::SIGN($significance)) {				return floor($number / $significance) * $significance;			} else {				return PHPExcel_Calculation_Functions::NaN();			}		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function FLOOR()	/**	 *	GCD	 *	 *	Returns the greatest common divisor of a series of numbers	 *	 *	@param	$array	Values to calculate the Greatest Common Divisor	 *	@return	int		Greatest Common Divisor	 */	public static function GCD() {		$returnValue = 1;		$allPoweredFactors = array();		// Loop through arguments		foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) {			if ($value == 0) {				break;			}			$myFactors = self::_factors($value);			$myCountedFactors = array_count_values($myFactors);			$allValuesFactors[] = $myCountedFactors;		}		$allValuesCount = count($allValuesFactors);		$mergedArray = $allValuesFactors[0];		for ($i=1;$i < $allValuesCount; ++$i) {			$mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]);		}		$mergedArrayValues = count($mergedArray);		if ($mergedArrayValues == 0) {			return $returnValue;		} elseif ($mergedArrayValues > 1) {			foreach($mergedArray as $mergedKey => $mergedValue) {				foreach($allValuesFactors as $highestPowerTest) {					foreach($highestPowerTest as $testKey => $testValue) {						if (($testKey == $mergedKey) && ($testValue < $mergedValue)) {							$mergedArray[$mergedKey] = $testValue;							$mergedValue = $testValue;						}					}				}			}			$returnValue = 1;			foreach($mergedArray as $key => $value) {				$returnValue *= pow($key,$value);			}			return $returnValue;		} else {			$keys = array_keys($mergedArray);			$key = $keys[0];			$value = $mergedArray[$key];			foreach($allValuesFactors as $testValue) {				foreach($testValue as $mergedKey => $mergedValue) {					if (($mergedKey == $key) && ($mergedValue < $value)) {						$value = $mergedValue;					}				}			}			return pow($key,$value);		}	}	//	function GCD()	/**	 *	INT	 *	 *	Casts a floating point value to an integer	 *	 *	@param	float	$number			Number to cast to an integer	 *	@return	integer	Integer value	 */	public static function INT($number) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		if (is_numeric($number)) {			return (int) floor($number);		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function INT()	/**	 *	LCM	 *	 *	Returns the lowest common multiplier of a series of numbers	 *	 *	@param	$array	Values to calculate the Lowest Common Multiplier	 *	@return	int		Lowest Common Multiplier	 */	public static function LCM() {		$returnValue = 1;		$allPoweredFactors = array();		// Loop through arguments		foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) {			if (!is_numeric($value)) {				return PHPExcel_Calculation_Functions::VALUE();			}			if ($value == 0) {				return 0;			} elseif ($value < 0) {				return PHPExcel_Calculation_Functions::NaN();			}			$myFactors = self::_factors(floor($value));			$myCountedFactors = array_count_values($myFactors);			$myPoweredFactors = array();			foreach($myCountedFactors as $myCountedFactor => $myCountedPower) {				$myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower);			}			foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) {				if (array_key_exists($myPoweredValue,$allPoweredFactors)) {					if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) {						$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;					}				} else {					$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;				}			}		}		foreach($allPoweredFactors as $allPoweredFactor) {			$returnValue *= (integer) $allPoweredFactor;		}		return $returnValue;	}	//	function LCM()	/**	 *	LOG_BASE	 *	 *	Returns the logarithm of a number to a specified base. The default base is 10.	 *	 *	Excel Function:	 *		LOG(number[,base])	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	float	$value		The positive real number for which you want the logarithm	 *	@param	float	$base		The base of the logarithm. If base is omitted, it is assumed to be 10.	 *	@return	float	 */	public static function LOG_BASE($number, $base=10) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$base	= (is_null($base))	? 10 :	(float) PHPExcel_Calculation_Functions::flattenSingleValue($base);		return log($number, $base);	}	//	function LOG_BASE()	/**	 * MDETERM	 *	 * @param	array	$matrixValues	A matrix of values	 * @return	float	 */	public static function MDETERM($matrixValues) {		$matrixData = array();		if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); }		$row = $maxColumn = 0;		foreach($matrixValues as $matrixRow) {			$column = 0;			foreach($matrixRow as $matrixCell) {				if ((is_string($matrixCell)) || ($matrixCell === null)) {					return PHPExcel_Calculation_Functions::VALUE();				}				$matrixData[$column][$row] = $matrixCell;				++$column;			}			if ($column > $maxColumn) { $maxColumn = $column; }			++$row;		}		if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); }		try {			$matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData);			return $matrix->det();		} catch (Exception $ex) {			return PHPExcel_Calculation_Functions::VALUE();		}	}	//	function MDETERM()	/**	 * MINVERSE	 *	 * @param	array	$matrixValues	A matrix of values	 * @return	array	 */	public static function MINVERSE($matrixValues) {		$matrixData = array();		if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); }		$row = $maxColumn = 0;		foreach($matrixValues as $matrixRow) {			$column = 0;			foreach($matrixRow as $matrixCell) {				if ((is_string($matrixCell)) || ($matrixCell === null)) {					return PHPExcel_Calculation_Functions::VALUE();				}				$matrixData[$column][$row] = $matrixCell;				++$column;			}			if ($column > $maxColumn) { $maxColumn = $column; }			++$row;		}		if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); }		try {			$matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData);			return $matrix->inverse()->getArray();		} catch (Exception $ex) {			return PHPExcel_Calculation_Functions::VALUE();		}	}	//	function MINVERSE()	/**	 * MMULT	 *	 * @param	array	$matrixData1	A matrix of values	 * @param	array	$matrixData2	A matrix of values	 * @return	array	 */	public static function MMULT($matrixData1,$matrixData2) {		$matrixAData = $matrixBData = array();		if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); }		if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); }		$rowA = 0;		foreach($matrixData1 as $matrixRow) {			$columnA = 0;			foreach($matrixRow as $matrixCell) {				if ((is_string($matrixCell)) || ($matrixCell === null)) {					return PHPExcel_Calculation_Functions::VALUE();				}				$matrixAData[$rowA][$columnA] = $matrixCell;				++$columnA;			}			++$rowA;		}		try {			$matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData);			$rowB = 0;			foreach($matrixData2 as $matrixRow) {				$columnB = 0;				foreach($matrixRow as $matrixCell) {					if ((is_string($matrixCell)) || ($matrixCell === null)) {						return PHPExcel_Calculation_Functions::VALUE();					}					$matrixBData[$rowB][$columnB] = $matrixCell;					++$columnB;				}				++$rowB;			}			$matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData);			if (($rowA != $columnB) || ($rowB != $columnA)) {				return PHPExcel_Calculation_Functions::VALUE();			}			return $matrixA->times($matrixB)->getArray();		} catch (Exception $ex) {			return PHPExcel_Calculation_Functions::VALUE();		}	}	//	function MMULT()	/**	 * MOD	 *	 * @param	int		$a		Dividend	 * @param	int		$b		Divisor	 * @return	int		Remainder	 */	public static function MOD($a = 1, $b = 1) {		$a		= PHPExcel_Calculation_Functions::flattenSingleValue($a);		$b		= PHPExcel_Calculation_Functions::flattenSingleValue($b);		if ($b == 0.0) {			return PHPExcel_Calculation_Functions::DIV0();		} elseif (($a < 0.0) && ($b > 0.0)) {			return $b - fmod(abs($a),$b);		} elseif (($a > 0.0) && ($b < 0.0)) {			return $b + fmod($a,abs($b));		}		return fmod($a,$b);	}	//	function MOD()	/**	 *	MROUND	 *	 *	Rounds a number to the nearest multiple of a specified value	 *	 *	@param	float	$number			Number to round	 *	@param	int		$multiple		Multiple to which you want to round $number	 *	@return	float	Rounded Number	 */	public static function MROUND($number,$multiple) {		$number		= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$multiple	= PHPExcel_Calculation_Functions::flattenSingleValue($multiple);		if ((is_numeric($number)) && (is_numeric($multiple))) {			if ($multiple == 0) {				return 0;			}			if ((self::SIGN($number)) == (self::SIGN($multiple))) {				$multiplier = 1 / $multiple;				return round($number * $multiplier) / $multiplier;			}			return PHPExcel_Calculation_Functions::NaN();		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function MROUND()	/**	 *	MULTINOMIAL	 *	 *	Returns the ratio of the factorial of a sum of values to the product of factorials.	 *	 *	@param	array of mixed		Data Series	 *	@return	float	 */	public static function MULTINOMIAL() {		$summer = 0;		$divisor = 1;		// Loop through arguments		foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {			// Is it a numeric value?			if (is_numeric($arg)) {				if ($arg < 1) {					return PHPExcel_Calculation_Functions::NaN();				}				$summer += floor($arg);				$divisor *= self::FACT($arg);			} else {				return PHPExcel_Calculation_Functions::VALUE();			}		}		// Return		if ($summer > 0) {			$summer = self::FACT($summer);			return $summer / $divisor;		}		return 0;	}	//	function MULTINOMIAL()	/**	 *	ODD	 *	 *	Returns number rounded up to the nearest odd integer.	 *	 *	@param	float	$number			Number to round	 *	@return	int		Rounded Number	 */	public static function ODD($number) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		if (is_null($number)) {			return 1;		} elseif (is_numeric($number)) {			$significance = self::SIGN($number);			if ($significance == 0) {				return 1;			}			$result = self::CEILING($number,$significance);			if ($result == self::EVEN($result)) {				$result += $significance;			}			return (int) $result;		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function ODD()	/**	 *	POWER	 *	 *	Computes x raised to the power y.	 *	 *	@param	float		$x	 *	@param	float		$y	 *	@return	float	 */	public static function POWER($x = 0, $y = 2) {		$x	= PHPExcel_Calculation_Functions::flattenSingleValue($x);		$y	= PHPExcel_Calculation_Functions::flattenSingleValue($y);		// Validate parameters		if ($x == 0 && $y <= 0) {			return PHPExcel_Calculation_Functions::DIV0();		}		// Return		return pow($x, $y);	}	//	function POWER()	/**	 *	PRODUCT	 *	 *	PRODUCT returns the product of all the values and cells referenced in the argument list.	 *	 *	Excel Function:	 *		PRODUCT(value1[,value2[, ...]])	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	mixed		$arg,...		Data values	 *	@return	float	 */	public static function PRODUCT() {		// Return value		$returnValue = null;		// Loop through arguments		foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {			// Is it a numeric value?			if ((is_numeric($arg)) && (!is_string($arg))) {				if (is_null($returnValue)) {					$returnValue = $arg;				} else {					$returnValue *= $arg;				}			}		}		// Return		if (is_null($returnValue)) {			return 0;		}		return $returnValue;	}	//	function PRODUCT()	/**	 *	QUOTIENT	 *	 *	QUOTIENT function returns the integer portion of a division. Numerator is the divided number	 *		and denominator is the divisor.	 *	 *	Excel Function:	 *		QUOTIENT(value1[,value2[, ...]])	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	mixed		$arg,...		Data values	 *	@return	float	 */	public static function QUOTIENT() {		// Return value		$returnValue = null;		// Loop through arguments		foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {			// Is it a numeric value?			if ((is_numeric($arg)) && (!is_string($arg))) {				if (is_null($returnValue)) {					$returnValue = ($arg == 0) ? 0 : $arg;				} else {					if (($returnValue == 0) || ($arg == 0)) {						$returnValue = 0;					} else {						$returnValue /= $arg;					}				}			}		}		// Return		return intval($returnValue);	}	//	function QUOTIENT()	/**	 * RAND	 *	 * @param	int		$min	Minimal value	 * @param	int		$max	Maximal value	 * @return	int		Random number	 */	public static function RAND($min = 0, $max = 0) {		$min		= PHPExcel_Calculation_Functions::flattenSingleValue($min);		$max		= PHPExcel_Calculation_Functions::flattenSingleValue($max);		if ($min == 0 && $max == 0) {			return (rand(0,10000000)) / 10000000;		} else {			return rand($min, $max);		}	}	//	function RAND()	public static function ROMAN($aValue, $style=0) {		$aValue	= (integer) PHPExcel_Calculation_Functions::flattenSingleValue($aValue);		$style	= (is_null($style))	? 0 :	(integer) PHPExcel_Calculation_Functions::flattenSingleValue($style);		if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) {			return PHPExcel_Calculation_Functions::VALUE();		}		if ($aValue == 0) {			return '';		}		$mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM');		$cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM');		$tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC');		$ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX');		$roman = '';		while ($aValue > 5999) {			$roman .= 'M';			$aValue -= 1000;		}		$m = self::_romanCut($aValue, 1000);	$aValue %= 1000;		$c = self::_romanCut($aValue, 100);		$aValue %= 100;		$t = self::_romanCut($aValue, 10);		$aValue %= 10;		return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue];	}	//	function ROMAN()	/**	 *	ROUNDUP	 *	 *	Rounds a number up to a specified number of decimal places	 *	 *	@param	float	$number			Number to round	 *	@param	int		$digits			Number of digits to which you want to round $number	 *	@return	float	Rounded Number	 */	public static function ROUNDUP($number,$digits) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$digits	= PHPExcel_Calculation_Functions::flattenSingleValue($digits);		if ((is_numeric($number)) && (is_numeric($digits))) {			$significance = pow(10,$digits);			if ($number < 0.0) {				return floor($number * $significance) / $significance;			} else {				return ceil($number * $significance) / $significance;			}		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function ROUNDUP()	/**	 *	ROUNDDOWN	 *	 *	Rounds a number down to a specified number of decimal places	 *	 *	@param	float	$number			Number to round	 *	@param	int		$digits			Number of digits to which you want to round $number	 *	@return	float	Rounded Number	 */	public static function ROUNDDOWN($number,$digits) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		$digits	= PHPExcel_Calculation_Functions::flattenSingleValue($digits);		if ((is_numeric($number)) && (is_numeric($digits))) {			$significance = pow(10,$digits);			if ($number < 0.0) {				return ceil($number * $significance) / $significance;			} else {				return floor($number * $significance) / $significance;			}		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function ROUNDDOWN()	/**	 *	SERIESSUM	 *	 *	Returns the sum of a power series	 *	 *	@param	float			$x	Input value to the power series	 *	@param	float			$n	Initial power to which you want to raise $x	 *	@param	float			$m	Step by which to increase $n for each term in the series	 *	@param	array of mixed		Data Series	 *	@return	float	 */	public static function SERIESSUM() {		// Return value		$returnValue = 0;		// Loop through arguments		$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());		$x = array_shift($aArgs);		$n = array_shift($aArgs);		$m = array_shift($aArgs);		if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) {			// Calculate			$i = 0;			foreach($aArgs as $arg) {				// Is it a numeric value?				if ((is_numeric($arg)) && (!is_string($arg))) {					$returnValue += $arg * pow($x,$n + ($m * $i++));				} else {					return PHPExcel_Calculation_Functions::VALUE();				}			}			// Return			return $returnValue;		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function SERIESSUM()	/**	 *	SIGN	 *	 *	Determines the sign of a number. Returns 1 if the number is positive, zero (0)	 *	if the number is 0, and -1 if the number is negative.	 *	 *	@param	float	$number			Number to round	 *	@return	int		sign value	 */	public static function SIGN($number) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		if (is_numeric($number)) {			if ($number == 0.0) {				return 0;			}			return $number / abs($number);		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function SIGN()	/**	 *	SQRTPI	 *	 *	Returns the square root of (number * pi).	 *	 *	@param	float	$number		Number	 *	@return	float	Square Root of Number * Pi	 */	public static function SQRTPI($number) {		$number	= PHPExcel_Calculation_Functions::flattenSingleValue($number);		if (is_numeric($number)) {			if ($number < 0) {				return PHPExcel_Calculation_Functions::NaN();			}			return sqrt($number * M_PI) ;		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function SQRTPI()	/**	 *	SUBTOTAL	 *	 *	Returns a subtotal in a list or database.	 *	 *	@param	int		the number 1 to 11 that specifies which function to	 *					use in calculating subtotals within a list.	 *	@param	array of mixed		Data Series	 *	@return	float	 */	public static function SUBTOTAL() {		$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());		// Calculate		$subtotal = array_shift($aArgs);		if ((is_numeric($subtotal)) && (!is_string($subtotal))) {			switch($subtotal) {				case 1	:					return PHPExcel_Calculation_Statistical::AVERAGE($aArgs);					break;				case 2	:					return PHPExcel_Calculation_Statistical::COUNT($aArgs);					break;				case 3	:					return PHPExcel_Calculation_Statistical::COUNTA($aArgs);					break;				case 4	:					return PHPExcel_Calculation_Statistical::MAX($aArgs);					break;				case 5	:					return PHPExcel_Calculation_Statistical::MIN($aArgs);					break;				case 6	:					return self::PRODUCT($aArgs);					break;				case 7	:					return PHPExcel_Calculation_Statistical::STDEV($aArgs);					break;				case 8	:					return PHPExcel_Calculation_Statistical::STDEVP($aArgs);					break;				case 9	:					return self::SUM($aArgs);					break;				case 10	:					return PHPExcel_Calculation_Statistical::VARFunc($aArgs);					break;				case 11	:					return PHPExcel_Calculation_Statistical::VARP($aArgs);					break;			}		}		return PHPExcel_Calculation_Functions::VALUE();	}	//	function SUBTOTAL()	/**	 *	SUM	 *	 *	SUM computes the sum of all the values and cells referenced in the argument list.	 *	 *	Excel Function:	 *		SUM(value1[,value2[, ...]])	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	mixed		$arg,...		Data values	 *	@return	float	 */	public static function SUM() {		// Return value		$returnValue = 0;		// Loop through the arguments		foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {			// Is it a numeric value?			if ((is_numeric($arg)) && (!is_string($arg))) {				$returnValue += $arg;			}		}		// Return		return $returnValue;	}	//	function SUM()	/**	 *	SUMIF	 *	 *	Counts the number of cells that contain numbers within the list of arguments	 *	 *	Excel Function:	 *		SUMIF(value1[,value2[, ...]],condition)	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	mixed		$arg,...		Data values	 *	@param	string		$condition		The criteria that defines which cells will be summed.	 *	@return	float	 */	public static function SUMIF($aArgs,$condition,$sumArgs = array()) {		// Return value		$returnValue = 0;		$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);		$sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs);		if (count($sumArgs) == 0) {			$sumArgs = $aArgs;		}		$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);		// Loop through arguments		foreach ($aArgs as $key => $arg) {			if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }			$testCondition = '='.$arg.$condition;			if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {				// Is it a value within our criteria				$returnValue += $sumArgs[$key];			}		}		// Return		return $returnValue;	}	//	function SUMIF()	/**	 * SUMPRODUCT	 *	 * @param	mixed	$value	Value to check	 * @return	float	 */	public static function SUMPRODUCT() {		$arrayList = func_get_args();		$wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList));		$wrkCellCount = count($wrkArray);		foreach($arrayList as $matrixData) {			$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData);			$count = count($array2);			if ($wrkCellCount != $count) {				return PHPExcel_Calculation_Functions::VALUE();			}			foreach ($array2 as $i => $val) {				if (((is_numeric($wrkArray[$i])) && (!is_string($wrkArray[$i]))) &&					((is_numeric($val)) && (!is_string($val)))) {					$wrkArray[$i] *= $val;				}			}		}		return array_sum($wrkArray);	}	//	function SUMPRODUCT()	/**	 *	SUMSQ	 *	 *	SUMSQ returns the sum of the squares of the arguments	 *	 *	Excel Function:	 *		SUMSQ(value1[,value2[, ...]])	 *	 *	@access	public	 *	@category Mathematical and Trigonometric Functions	 *	@param	mixed		$arg,...		Data values	 *	@return	float	 */	public static function SUMSQ() {		// Return value		$returnValue = 0;		// Loop through arguments		foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {			// Is it a numeric value?			if ((is_numeric($arg)) && (!is_string($arg))) {				$returnValue += ($arg * $arg);			}		}		// Return		return $returnValue;	}	//	function SUMSQ()	/**	 * SUMX2MY2	 *	 * @param	mixed	$value	Value to check	 * @return	float	 */	public static function SUMX2MY2($matrixData1,$matrixData2) {		$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);		$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);		$count1 = count($array1);		$count2 = count($array2);		if ($count1 < $count2) {			$count = $count1;		} else {			$count = $count2;		}		$result = 0;		for ($i = 0; $i < $count; ++$i) {			if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&				((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {				$result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]);			}		}		return $result;	}	//	function SUMX2MY2()	/**	 * SUMX2PY2	 *	 * @param	mixed	$value	Value to check	 * @return	float	 */	public static function SUMX2PY2($matrixData1,$matrixData2) {		$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);		$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);		$count1 = count($array1);		$count2 = count($array2);		if ($count1 < $count2) {			$count = $count1;		} else {			$count = $count2;		}		$result = 0;		for ($i = 0; $i < $count; ++$i) {			if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&				((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {				$result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]);			}		}		return $result;	}	//	function SUMX2PY2()	/**	 * SUMXMY2	 *	 * @param	mixed	$value	Value to check	 * @return	float	 */	public static function SUMXMY2($matrixData1,$matrixData2) {		$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);		$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);		$count1 = count($array1);		$count2 = count($array2);		if ($count1 < $count2) {			$count = $count1;		} else {			$count = $count2;		}		$result = 0;		for ($i = 0; $i < $count; ++$i) {			if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&				((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {				$result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]);			}		}		return $result;	}	//	function SUMXMY2()	/**	 *	TRUNC	 *	 *	Truncates value to the number of fractional digits by number_digits.	 *	 *	@param	float		$value	 *	@param	int			$number_digits	 *	@return	float		Truncated value	 */	public static function TRUNC($value = 0, $number_digits = 0) {		$value			= PHPExcel_Calculation_Functions::flattenSingleValue($value);		$number_digits	= PHPExcel_Calculation_Functions::flattenSingleValue($number_digits);		// Validate parameters		if ($number_digits < 0) {			return PHPExcel_Calculation_Functions::VALUE();		}		// Truncate		if ($number_digits > 0) {			$value = $value * pow(10, $number_digits);		}		$value = intval($value);		if ($number_digits > 0) {			$value = $value / pow(10, $number_digits);		}		// Return		return $value;	}	//	function TRUNC()}	//	class PHPExcel_Calculation_MathTrig
 |