[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** PHPExcel root directory */ 4 if (!defined('PHPEXCEL_ROOT')) { 5 /** 6 * @ignore 7 */ 8 define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); 9 require (PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); 10 } 11 12 /** 13 * PHPExcel_Calculation_MathTrig 14 * 15 * Copyright (c) 2006 - 2015 PHPExcel 16 * 17 * This library is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU Lesser General Public 19 * License as published by the Free Software Foundation; either 20 * version 2.1 of the License, or (at your option) any later version. 21 * 22 * This library is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 * Lesser General Public License for more details. 26 * 27 * You should have received a copy of the GNU Lesser General Public 28 * License along with this library; if not, write to the Free Software 29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 30 * 31 * @category PHPExcel 32 * @package PHPExcel_Calculation 33 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 34 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 35 * @version ##VERSION##, ##DATE## 36 */ 37 class PHPExcel_Calculation_MathTrig 38 { 39 // 40 // Private method to return an array of the factors of the input value 41 // 42 private static function factors($value) 43 { 44 $startVal = floor(sqrt($value)); 45 46 $factorArray = array(); 47 for ($i = $startVal; $i > 1; --$i) { 48 if (($value % $i) == 0) { 49 $factorArray = array_merge($factorArray, self::factors($value / $i)); 50 $factorArray = array_merge($factorArray, self::factors($i)); 51 if ($i <= sqrt($value)) { 52 break; 53 } 54 } 55 } 56 if (!empty($factorArray)) { 57 rsort($factorArray); 58 return $factorArray; 59 } else { 60 return array((integer) $value); 61 } 62 } 63 64 65 private static function romanCut($num, $n) 66 { 67 return ($num - ($num % $n ) ) / $n; 68 } 69 70 71 /** 72 * ATAN2 73 * 74 * This function calculates the arc tangent of the two variables x and y. It is similar to 75 * calculating the arc tangent of y รท x, except that the signs of both arguments are used 76 * to determine the quadrant of the result. 77 * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a 78 * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between 79 * -pi and pi, excluding -pi. 80 * 81 * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard 82 * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function. 83 * 84 * Excel Function: 85 * ATAN2(xCoordinate,yCoordinate) 86 * 87 * @access public 88 * @category Mathematical and Trigonometric Functions 89 * @param float $xCoordinate The x-coordinate of the point. 90 * @param float $yCoordinate The y-coordinate of the point. 91 * @return float The inverse tangent of the specified x- and y-coordinates. 92 */ 93 public static function ATAN2($xCoordinate = null, $yCoordinate = null) 94 { 95 $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); 96 $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); 97 98 $xCoordinate = ($xCoordinate !== null) ? $xCoordinate : 0.0; 99 $yCoordinate = ($yCoordinate !== null) ? $yCoordinate : 0.0; 100 101 if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && 102 ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { 103 $xCoordinate = (float) $xCoordinate; 104 $yCoordinate = (float) $yCoordinate; 105 106 if (($xCoordinate == 0) && ($yCoordinate == 0)) { 107 return PHPExcel_Calculation_Functions::DIV0(); 108 } 109 110 return atan2($yCoordinate, $xCoordinate); 111 } 112 return PHPExcel_Calculation_Functions::VALUE(); 113 } 114 115 116 /** 117 * CEILING 118 * 119 * Returns number rounded up, away from zero, to the nearest multiple of significance. 120 * For example, if you want to avoid using pennies in your prices and your product is 121 * priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the 122 * nearest nickel. 123 * 124 * Excel Function: 125 * CEILING(number[,significance]) 126 * 127 * @access public 128 * @category Mathematical and Trigonometric Functions 129 * @param float $number The number you want to round. 130 * @param float $significance The multiple to which you want to round. 131 * @return float Rounded Number 132 */ 133 public static function CEILING($number, $significance = null) 134 { 135 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 136 $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); 137 138 if ((is_null($significance)) && 139 (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { 140 $significance = $number / abs($number); 141 } 142 143 if ((is_numeric($number)) && (is_numeric($significance))) { 144 if (($number == 0.0 ) || ($significance == 0.0)) { 145 return 0.0; 146 } elseif (self::SIGN($number) == self::SIGN($significance)) { 147 return ceil($number / $significance) * $significance; 148 } else { 149 return PHPExcel_Calculation_Functions::NaN(); 150 } 151 } 152 return PHPExcel_Calculation_Functions::VALUE(); 153 } 154 155 156 /** 157 * COMBIN 158 * 159 * Returns the number of combinations for a given number of items. Use COMBIN to 160 * determine the total possible number of groups for a given number of items. 161 * 162 * Excel Function: 163 * COMBIN(numObjs,numInSet) 164 * 165 * @access public 166 * @category Mathematical and Trigonometric Functions 167 * @param int $numObjs Number of different objects 168 * @param int $numInSet Number of objects in each combination 169 * @return int Number of combinations 170 */ 171 public static function COMBIN($numObjs, $numInSet) 172 { 173 $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); 174 $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); 175 176 if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { 177 if ($numObjs < $numInSet) { 178 return PHPExcel_Calculation_Functions::NaN(); 179 } elseif ($numInSet < 0) { 180 return PHPExcel_Calculation_Functions::NaN(); 181 } 182 return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); 183 } 184 return PHPExcel_Calculation_Functions::VALUE(); 185 } 186 187 188 /** 189 * EVEN 190 * 191 * Returns number rounded up to the nearest even integer. 192 * You can use this function for processing items that come in twos. For example, 193 * a packing crate accepts rows of one or two items. The crate is full when 194 * the number of items, rounded up to the nearest two, matches the crate's 195 * capacity. 196 * 197 * Excel Function: 198 * EVEN(number) 199 * 200 * @access public 201 * @category Mathematical and Trigonometric Functions 202 * @param float $number Number to round 203 * @return int Rounded Number 204 */ 205 public static function EVEN($number) 206 { 207 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 208 209 if (is_null($number)) { 210 return 0; 211 } elseif (is_bool($number)) { 212 $number = (int) $number; 213 } 214 215 if (is_numeric($number)) { 216 $significance = 2 * self::SIGN($number); 217 return (int) self::CEILING($number, $significance); 218 } 219 return PHPExcel_Calculation_Functions::VALUE(); 220 } 221 222 223 /** 224 * FACT 225 * 226 * Returns the factorial of a number. 227 * The factorial of a number is equal to 1*2*3*...* number. 228 * 229 * Excel Function: 230 * FACT(factVal) 231 * 232 * @access public 233 * @category Mathematical and Trigonometric Functions 234 * @param float $factVal Factorial Value 235 * @return int Factorial 236 */ 237 public static function FACT($factVal) 238 { 239 $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); 240 241 if (is_numeric($factVal)) { 242 if ($factVal < 0) { 243 return PHPExcel_Calculation_Functions::NaN(); 244 } 245 $factLoop = floor($factVal); 246 if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { 247 if ($factVal > $factLoop) { 248 return PHPExcel_Calculation_Functions::NaN(); 249 } 250 } 251 252 $factorial = 1; 253 while ($factLoop > 1) { 254 $factorial *= $factLoop--; 255 } 256 return $factorial ; 257 } 258 return PHPExcel_Calculation_Functions::VALUE(); 259 } 260 261 262 /** 263 * FACTDOUBLE 264 * 265 * Returns the double factorial of a number. 266 * 267 * Excel Function: 268 * FACTDOUBLE(factVal) 269 * 270 * @access public 271 * @category Mathematical and Trigonometric Functions 272 * @param float $factVal Factorial Value 273 * @return int Double Factorial 274 */ 275 public static function FACTDOUBLE($factVal) 276 { 277 $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); 278 279 if (is_numeric($factLoop)) { 280 $factLoop = floor($factLoop); 281 if ($factVal < 0) { 282 return PHPExcel_Calculation_Functions::NaN(); 283 } 284 $factorial = 1; 285 while ($factLoop > 1) { 286 $factorial *= $factLoop--; 287 --$factLoop; 288 } 289 return $factorial ; 290 } 291 return PHPExcel_Calculation_Functions::VALUE(); 292 } 293 294 295 /** 296 * FLOOR 297 * 298 * Rounds number down, toward zero, to the nearest multiple of significance. 299 * 300 * Excel Function: 301 * FLOOR(number[,significance]) 302 * 303 * @access public 304 * @category Mathematical and Trigonometric Functions 305 * @param float $number Number to round 306 * @param float $significance Significance 307 * @return float Rounded Number 308 */ 309 public static function FLOOR($number, $significance = null) 310 { 311 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 312 $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); 313 314 if ((is_null($significance)) && 315 (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { 316 $significance = $number/abs($number); 317 } 318 319 if ((is_numeric($number)) && (is_numeric($significance))) { 320 if ($significance == 0.0) { 321 return PHPExcel_Calculation_Functions::DIV0(); 322 } elseif ($number == 0.0) { 323 return 0.0; 324 } elseif (self::SIGN($number) == self::SIGN($significance)) { 325 return floor($number / $significance) * $significance; 326 } else { 327 return PHPExcel_Calculation_Functions::NaN(); 328 } 329 } 330 331 return PHPExcel_Calculation_Functions::VALUE(); 332 } 333 334 335 /** 336 * GCD 337 * 338 * Returns the greatest common divisor of a series of numbers. 339 * The greatest common divisor is the largest integer that divides both 340 * number1 and number2 without a remainder. 341 * 342 * Excel Function: 343 * GCD(number1[,number2[, ...]]) 344 * 345 * @access public 346 * @category Mathematical and Trigonometric Functions 347 * @param mixed $arg,... Data values 348 * @return integer Greatest Common Divisor 349 */ 350 public static function GCD() 351 { 352 $returnValue = 1; 353 $allValuesFactors = array(); 354 // Loop through arguments 355 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { 356 if (!is_numeric($value)) { 357 return PHPExcel_Calculation_Functions::VALUE(); 358 } elseif ($value == 0) { 359 continue; 360 } elseif ($value < 0) { 361 return PHPExcel_Calculation_Functions::NaN(); 362 } 363 $myFactors = self::factors($value); 364 $myCountedFactors = array_count_values($myFactors); 365 $allValuesFactors[] = $myCountedFactors; 366 } 367 $allValuesCount = count($allValuesFactors); 368 if ($allValuesCount == 0) { 369 return 0; 370 } 371 372 $mergedArray = $allValuesFactors[0]; 373 for ($i=1; $i < $allValuesCount; ++$i) { 374 $mergedArray = array_intersect_key($mergedArray, $allValuesFactors[$i]); 375 } 376 $mergedArrayValues = count($mergedArray); 377 if ($mergedArrayValues == 0) { 378 return $returnValue; 379 } elseif ($mergedArrayValues > 1) { 380 foreach ($mergedArray as $mergedKey => $mergedValue) { 381 foreach ($allValuesFactors as $highestPowerTest) { 382 foreach ($highestPowerTest as $testKey => $testValue) { 383 if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { 384 $mergedArray[$mergedKey] = $testValue; 385 $mergedValue = $testValue; 386 } 387 } 388 } 389 } 390 391 $returnValue = 1; 392 foreach ($mergedArray as $key => $value) { 393 $returnValue *= pow($key, $value); 394 } 395 return $returnValue; 396 } else { 397 $keys = array_keys($mergedArray); 398 $key = $keys[0]; 399 $value = $mergedArray[$key]; 400 foreach ($allValuesFactors as $testValue) { 401 foreach ($testValue as $mergedKey => $mergedValue) { 402 if (($mergedKey == $key) && ($mergedValue < $value)) { 403 $value = $mergedValue; 404 } 405 } 406 } 407 return pow($key, $value); 408 } 409 } 410 411 412 /** 413 * INT 414 * 415 * Casts a floating point value to an integer 416 * 417 * Excel Function: 418 * INT(number) 419 * 420 * @access public 421 * @category Mathematical and Trigonometric Functions 422 * @param float $number Number to cast to an integer 423 * @return integer Integer value 424 */ 425 public static function INT($number) 426 { 427 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 428 429 if (is_null($number)) { 430 return 0; 431 } elseif (is_bool($number)) { 432 return (int) $number; 433 } 434 if (is_numeric($number)) { 435 return (int) floor($number); 436 } 437 return PHPExcel_Calculation_Functions::VALUE(); 438 } 439 440 441 /** 442 * LCM 443 * 444 * Returns the lowest common multiplier of a series of numbers 445 * The least common multiple is the smallest positive integer that is a multiple 446 * of all integer arguments number1, number2, and so on. Use LCM to add fractions 447 * with different denominators. 448 * 449 * Excel Function: 450 * LCM(number1[,number2[, ...]]) 451 * 452 * @access public 453 * @category Mathematical and Trigonometric Functions 454 * @param mixed $arg,... Data values 455 * @return int Lowest Common Multiplier 456 */ 457 public static function LCM() 458 { 459 $returnValue = 1; 460 $allPoweredFactors = array(); 461 // Loop through arguments 462 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { 463 if (!is_numeric($value)) { 464 return PHPExcel_Calculation_Functions::VALUE(); 465 } 466 if ($value == 0) { 467 return 0; 468 } elseif ($value < 0) { 469 return PHPExcel_Calculation_Functions::NaN(); 470 } 471 $myFactors = self::factors(floor($value)); 472 $myCountedFactors = array_count_values($myFactors); 473 $myPoweredFactors = array(); 474 foreach ($myCountedFactors as $myCountedFactor => $myCountedPower) { 475 $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor, $myCountedPower); 476 } 477 foreach ($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { 478 if (array_key_exists($myPoweredValue, $allPoweredFactors)) { 479 if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { 480 $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; 481 } 482 } else { 483 $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; 484 } 485 } 486 } 487 foreach ($allPoweredFactors as $allPoweredFactor) { 488 $returnValue *= (integer) $allPoweredFactor; 489 } 490 return $returnValue; 491 } 492 493 494 /** 495 * LOG_BASE 496 * 497 * Returns the logarithm of a number to a specified base. The default base is 10. 498 * 499 * Excel Function: 500 * LOG(number[,base]) 501 * 502 * @access public 503 * @category Mathematical and Trigonometric Functions 504 * @param float $number The positive real number for which you want the logarithm 505 * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. 506 * @return float 507 */ 508 public static function LOG_BASE($number = null, $base = 10) 509 { 510 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 511 $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); 512 513 if ((!is_numeric($base)) || (!is_numeric($number))) { 514 return PHPExcel_Calculation_Functions::VALUE(); 515 } 516 if (($base <= 0) || ($number <= 0)) { 517 return PHPExcel_Calculation_Functions::NaN(); 518 } 519 return log($number, $base); 520 } 521 522 523 /** 524 * MDETERM 525 * 526 * Returns the matrix determinant of an array. 527 * 528 * Excel Function: 529 * MDETERM(array) 530 * 531 * @access public 532 * @category Mathematical and Trigonometric Functions 533 * @param array $matrixValues A matrix of values 534 * @return float 535 */ 536 public static function MDETERM($matrixValues) 537 { 538 $matrixData = array(); 539 if (!is_array($matrixValues)) { 540 $matrixValues = array(array($matrixValues)); 541 } 542 543 $row = $maxColumn = 0; 544 foreach ($matrixValues as $matrixRow) { 545 if (!is_array($matrixRow)) { 546 $matrixRow = array($matrixRow); 547 } 548 $column = 0; 549 foreach ($matrixRow as $matrixCell) { 550 if ((is_string($matrixCell)) || ($matrixCell === null)) { 551 return PHPExcel_Calculation_Functions::VALUE(); 552 } 553 $matrixData[$column][$row] = $matrixCell; 554 ++$column; 555 } 556 if ($column > $maxColumn) { 557 $maxColumn = $column; 558 } 559 ++$row; 560 } 561 if ($row != $maxColumn) { 562 return PHPExcel_Calculation_Functions::VALUE(); 563 } 564 565 try { 566 $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); 567 return $matrix->det(); 568 } catch (PHPExcel_Exception $ex) { 569 return PHPExcel_Calculation_Functions::VALUE(); 570 } 571 } 572 573 574 /** 575 * MINVERSE 576 * 577 * Returns the inverse matrix for the matrix stored in an array. 578 * 579 * Excel Function: 580 * MINVERSE(array) 581 * 582 * @access public 583 * @category Mathematical and Trigonometric Functions 584 * @param array $matrixValues A matrix of values 585 * @return array 586 */ 587 public static function MINVERSE($matrixValues) 588 { 589 $matrixData = array(); 590 if (!is_array($matrixValues)) { 591 $matrixValues = array(array($matrixValues)); 592 } 593 594 $row = $maxColumn = 0; 595 foreach ($matrixValues as $matrixRow) { 596 if (!is_array($matrixRow)) { 597 $matrixRow = array($matrixRow); 598 } 599 $column = 0; 600 foreach ($matrixRow as $matrixCell) { 601 if ((is_string($matrixCell)) || ($matrixCell === null)) { 602 return PHPExcel_Calculation_Functions::VALUE(); 603 } 604 $matrixData[$column][$row] = $matrixCell; 605 ++$column; 606 } 607 if ($column > $maxColumn) { 608 $maxColumn = $column; 609 } 610 ++$row; 611 } 612 if ($row != $maxColumn) { 613 return PHPExcel_Calculation_Functions::VALUE(); 614 } 615 616 try { 617 $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); 618 return $matrix->inverse()->getArray(); 619 } catch (PHPExcel_Exception $ex) { 620 return PHPExcel_Calculation_Functions::VALUE(); 621 } 622 } 623 624 625 /** 626 * MMULT 627 * 628 * @param array $matrixData1 A matrix of values 629 * @param array $matrixData2 A matrix of values 630 * @return array 631 */ 632 public static function MMULT($matrixData1, $matrixData2) 633 { 634 $matrixAData = $matrixBData = array(); 635 if (!is_array($matrixData1)) { 636 $matrixData1 = array(array($matrixData1)); 637 } 638 if (!is_array($matrixData2)) { 639 $matrixData2 = array(array($matrixData2)); 640 } 641 642 try { 643 $rowA = 0; 644 foreach ($matrixData1 as $matrixRow) { 645 if (!is_array($matrixRow)) { 646 $matrixRow = array($matrixRow); 647 } 648 $columnA = 0; 649 foreach ($matrixRow as $matrixCell) { 650 if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { 651 return PHPExcel_Calculation_Functions::VALUE(); 652 } 653 $matrixAData[$rowA][$columnA] = $matrixCell; 654 ++$columnA; 655 } 656 ++$rowA; 657 } 658 $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); 659 $rowB = 0; 660 foreach ($matrixData2 as $matrixRow) { 661 if (!is_array($matrixRow)) { 662 $matrixRow = array($matrixRow); 663 } 664 $columnB = 0; 665 foreach ($matrixRow as $matrixCell) { 666 if ((!is_numeric($matrixCell)) || ($matrixCell === null)) { 667 return PHPExcel_Calculation_Functions::VALUE(); 668 } 669 $matrixBData[$rowB][$columnB] = $matrixCell; 670 ++$columnB; 671 } 672 ++$rowB; 673 } 674 $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); 675 676 if ($columnA != $rowB) { 677 return PHPExcel_Calculation_Functions::VALUE(); 678 } 679 680 return $matrixA->times($matrixB)->getArray(); 681 } catch (PHPExcel_Exception $ex) { 682 var_dump($ex->getMessage()); 683 return PHPExcel_Calculation_Functions::VALUE(); 684 } 685 } 686 687 688 /** 689 * MOD 690 * 691 * @param int $a Dividend 692 * @param int $b Divisor 693 * @return int Remainder 694 */ 695 public static function MOD($a = 1, $b = 1) 696 { 697 $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); 698 $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); 699 700 if ($b == 0.0) { 701 return PHPExcel_Calculation_Functions::DIV0(); 702 } elseif (($a < 0.0) && ($b > 0.0)) { 703 return $b - fmod(abs($a), $b); 704 } elseif (($a > 0.0) && ($b < 0.0)) { 705 return $b + fmod($a, abs($b)); 706 } 707 708 return fmod($a, $b); 709 } 710 711 712 /** 713 * MROUND 714 * 715 * Rounds a number to the nearest multiple of a specified value 716 * 717 * @param float $number Number to round 718 * @param int $multiple Multiple to which you want to round $number 719 * @return float Rounded Number 720 */ 721 public static function MROUND($number, $multiple) 722 { 723 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 724 $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); 725 726 if ((is_numeric($number)) && (is_numeric($multiple))) { 727 if ($multiple == 0) { 728 return 0; 729 } 730 if ((self::SIGN($number)) == (self::SIGN($multiple))) { 731 $multiplier = 1 / $multiple; 732 return round($number * $multiplier) / $multiplier; 733 } 734 return PHPExcel_Calculation_Functions::NaN(); 735 } 736 return PHPExcel_Calculation_Functions::VALUE(); 737 } 738 739 740 /** 741 * MULTINOMIAL 742 * 743 * Returns the ratio of the factorial of a sum of values to the product of factorials. 744 * 745 * @param array of mixed Data Series 746 * @return float 747 */ 748 public static function MULTINOMIAL() 749 { 750 $summer = 0; 751 $divisor = 1; 752 // Loop through arguments 753 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { 754 // Is it a numeric value? 755 if (is_numeric($arg)) { 756 if ($arg < 1) { 757 return PHPExcel_Calculation_Functions::NaN(); 758 } 759 $summer += floor($arg); 760 $divisor *= self::FACT($arg); 761 } else { 762 return PHPExcel_Calculation_Functions::VALUE(); 763 } 764 } 765 766 // Return 767 if ($summer > 0) { 768 $summer = self::FACT($summer); 769 return $summer / $divisor; 770 } 771 return 0; 772 } 773 774 775 /** 776 * ODD 777 * 778 * Returns number rounded up to the nearest odd integer. 779 * 780 * @param float $number Number to round 781 * @return int Rounded Number 782 */ 783 public static function ODD($number) 784 { 785 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 786 787 if (is_null($number)) { 788 return 1; 789 } elseif (is_bool($number)) { 790 return 1; 791 } elseif (is_numeric($number)) { 792 $significance = self::SIGN($number); 793 if ($significance == 0) { 794 return 1; 795 } 796 797 $result = self::CEILING($number, $significance); 798 if ($result == self::EVEN($result)) { 799 $result += $significance; 800 } 801 802 return (int) $result; 803 } 804 return PHPExcel_Calculation_Functions::VALUE(); 805 } 806 807 808 /** 809 * POWER 810 * 811 * Computes x raised to the power y. 812 * 813 * @param float $x 814 * @param float $y 815 * @return float 816 */ 817 public static function POWER($x = 0, $y = 2) 818 { 819 $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); 820 $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); 821 822 // Validate parameters 823 if ($x == 0.0 && $y == 0.0) { 824 return PHPExcel_Calculation_Functions::NaN(); 825 } elseif ($x == 0.0 && $y < 0.0) { 826 return PHPExcel_Calculation_Functions::DIV0(); 827 } 828 829 // Return 830 $result = pow($x, $y); 831 return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); 832 } 833 834 835 /** 836 * PRODUCT 837 * 838 * PRODUCT returns the product of all the values and cells referenced in the argument list. 839 * 840 * Excel Function: 841 * PRODUCT(value1[,value2[, ...]]) 842 * 843 * @access public 844 * @category Mathematical and Trigonometric Functions 845 * @param mixed $arg,... Data values 846 * @return float 847 */ 848 public static function PRODUCT() 849 { 850 // Return value 851 $returnValue = null; 852 853 // Loop through arguments 854 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { 855 // Is it a numeric value? 856 if ((is_numeric($arg)) && (!is_string($arg))) { 857 if (is_null($returnValue)) { 858 $returnValue = $arg; 859 } else { 860 $returnValue *= $arg; 861 } 862 } 863 } 864 865 // Return 866 if (is_null($returnValue)) { 867 return 0; 868 } 869 return $returnValue; 870 } 871 872 873 /** 874 * QUOTIENT 875 * 876 * QUOTIENT function returns the integer portion of a division. Numerator is the divided number 877 * and denominator is the divisor. 878 * 879 * Excel Function: 880 * QUOTIENT(value1[,value2[, ...]]) 881 * 882 * @access public 883 * @category Mathematical and Trigonometric Functions 884 * @param mixed $arg,... Data values 885 * @return float 886 */ 887 public static function QUOTIENT() 888 { 889 // Return value 890 $returnValue = null; 891 892 // Loop through arguments 893 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { 894 // Is it a numeric value? 895 if ((is_numeric($arg)) && (!is_string($arg))) { 896 if (is_null($returnValue)) { 897 $returnValue = ($arg == 0) ? 0 : $arg; 898 } else { 899 if (($returnValue == 0) || ($arg == 0)) { 900 $returnValue = 0; 901 } else { 902 $returnValue /= $arg; 903 } 904 } 905 } 906 } 907 908 // Return 909 return intval($returnValue); 910 } 911 912 913 /** 914 * RAND 915 * 916 * @param int $min Minimal value 917 * @param int $max Maximal value 918 * @return int Random number 919 */ 920 public static function RAND($min = 0, $max = 0) 921 { 922 $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); 923 $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); 924 925 if ($min == 0 && $max == 0) { 926 return (mt_rand(0, 10000000)) / 10000000; 927 } else { 928 return mt_rand($min, $max); 929 } 930 } 931 932 933 public static function ROMAN($aValue, $style = 0) 934 { 935 $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); 936 $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); 937 if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { 938 return PHPExcel_Calculation_Functions::VALUE(); 939 } 940 $aValue = (integer) $aValue; 941 if ($aValue == 0) { 942 return ''; 943 } 944 945 $mill = array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); 946 $cent = array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); 947 $tens = array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); 948 $ones = array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); 949 950 $roman = ''; 951 while ($aValue > 5999) { 952 $roman .= 'M'; 953 $aValue -= 1000; 954 } 955 $m = self::romanCut($aValue, 1000); 956 $aValue %= 1000; 957 $c = self::romanCut($aValue, 100); 958 $aValue %= 100; 959 $t = self::romanCut($aValue, 10); 960 $aValue %= 10; 961 962 return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; 963 } 964 965 966 /** 967 * ROUNDUP 968 * 969 * Rounds a number up to a specified number of decimal places 970 * 971 * @param float $number Number to round 972 * @param int $digits Number of digits to which you want to round $number 973 * @return float Rounded Number 974 */ 975 public static function ROUNDUP($number, $digits) 976 { 977 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 978 $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); 979 980 if ((is_numeric($number)) && (is_numeric($digits))) { 981 $significance = pow(10, (int) $digits); 982 if ($number < 0.0) { 983 return floor($number * $significance) / $significance; 984 } else { 985 return ceil($number * $significance) / $significance; 986 } 987 } 988 return PHPExcel_Calculation_Functions::VALUE(); 989 } 990 991 992 /** 993 * ROUNDDOWN 994 * 995 * Rounds a number down to a specified number of decimal places 996 * 997 * @param float $number Number to round 998 * @param int $digits Number of digits to which you want to round $number 999 * @return float Rounded Number 1000 */ 1001 public static function ROUNDDOWN($number, $digits) 1002 { 1003 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 1004 $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); 1005 1006 if ((is_numeric($number)) && (is_numeric($digits))) { 1007 $significance = pow(10, (int) $digits); 1008 if ($number < 0.0) { 1009 return ceil($number * $significance) / $significance; 1010 } else { 1011 return floor($number * $significance) / $significance; 1012 } 1013 } 1014 return PHPExcel_Calculation_Functions::VALUE(); 1015 } 1016 1017 1018 /** 1019 * SERIESSUM 1020 * 1021 * Returns the sum of a power series 1022 * 1023 * @param float $x Input value to the power series 1024 * @param float $n Initial power to which you want to raise $x 1025 * @param float $m Step by which to increase $n for each term in the series 1026 * @param array of mixed Data Series 1027 * @return float 1028 */ 1029 public static function SERIESSUM() 1030 { 1031 $returnValue = 0; 1032 1033 // Loop through arguments 1034 $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); 1035 1036 $x = array_shift($aArgs); 1037 $n = array_shift($aArgs); 1038 $m = array_shift($aArgs); 1039 1040 if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { 1041 // Calculate 1042 $i = 0; 1043 foreach ($aArgs as $arg) { 1044 // Is it a numeric value? 1045 if ((is_numeric($arg)) && (!is_string($arg))) { 1046 $returnValue += $arg * pow($x, $n + ($m * $i++)); 1047 } else { 1048 return PHPExcel_Calculation_Functions::VALUE(); 1049 } 1050 } 1051 return $returnValue; 1052 } 1053 return PHPExcel_Calculation_Functions::VALUE(); 1054 } 1055 1056 1057 /** 1058 * SIGN 1059 * 1060 * Determines the sign of a number. Returns 1 if the number is positive, zero (0) 1061 * if the number is 0, and -1 if the number is negative. 1062 * 1063 * @param float $number Number to round 1064 * @return int sign value 1065 */ 1066 public static function SIGN($number) 1067 { 1068 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 1069 1070 if (is_bool($number)) { 1071 return (int) $number; 1072 } 1073 if (is_numeric($number)) { 1074 if ($number == 0.0) { 1075 return 0; 1076 } 1077 return $number / abs($number); 1078 } 1079 return PHPExcel_Calculation_Functions::VALUE(); 1080 } 1081 1082 1083 /** 1084 * SQRTPI 1085 * 1086 * Returns the square root of (number * pi). 1087 * 1088 * @param float $number Number 1089 * @return float Square Root of Number * Pi 1090 */ 1091 public static function SQRTPI($number) 1092 { 1093 $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); 1094 1095 if (is_numeric($number)) { 1096 if ($number < 0) { 1097 return PHPExcel_Calculation_Functions::NaN(); 1098 } 1099 return sqrt($number * M_PI) ; 1100 } 1101 return PHPExcel_Calculation_Functions::VALUE(); 1102 } 1103 1104 1105 /** 1106 * SUBTOTAL 1107 * 1108 * Returns a subtotal in a list or database. 1109 * 1110 * @param int the number 1 to 11 that specifies which function to 1111 * use in calculating subtotals within a list. 1112 * @param array of mixed Data Series 1113 * @return float 1114 */ 1115 public static function SUBTOTAL() 1116 { 1117 $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); 1118 1119 // Calculate 1120 $subtotal = array_shift($aArgs); 1121 1122 if ((is_numeric($subtotal)) && (!is_string($subtotal))) { 1123 switch ($subtotal) { 1124 case 1: 1125 return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); 1126 case 2: 1127 return PHPExcel_Calculation_Statistical::COUNT($aArgs); 1128 case 3: 1129 return PHPExcel_Calculation_Statistical::COUNTA($aArgs); 1130 case 4: 1131 return PHPExcel_Calculation_Statistical::MAX($aArgs); 1132 case 5: 1133 return PHPExcel_Calculation_Statistical::MIN($aArgs); 1134 case 6: 1135 return self::PRODUCT($aArgs); 1136 case 7: 1137 return PHPExcel_Calculation_Statistical::STDEV($aArgs); 1138 case 8: 1139 return PHPExcel_Calculation_Statistical::STDEVP($aArgs); 1140 case 9: 1141 return self::SUM($aArgs); 1142 case 10: 1143 return PHPExcel_Calculation_Statistical::VARFunc($aArgs); 1144 case 11: 1145 return PHPExcel_Calculation_Statistical::VARP($aArgs); 1146 } 1147 } 1148 return PHPExcel_Calculation_Functions::VALUE(); 1149 } 1150 1151 1152 /** 1153 * SUM 1154 * 1155 * SUM computes the sum of all the values and cells referenced in the argument list. 1156 * 1157 * Excel Function: 1158 * SUM(value1[,value2[, ...]]) 1159 * 1160 * @access public 1161 * @category Mathematical and Trigonometric Functions 1162 * @param mixed $arg,... Data values 1163 * @return float 1164 */ 1165 public static function SUM() 1166 { 1167 $returnValue = 0; 1168 1169 // Loop through the arguments 1170 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { 1171 // Is it a numeric value? 1172 if ((is_numeric($arg)) && (!is_string($arg))) { 1173 $returnValue += $arg; 1174 } 1175 } 1176 1177 return $returnValue; 1178 } 1179 1180 1181 /** 1182 * SUMIF 1183 * 1184 * Counts the number of cells that contain numbers within the list of arguments 1185 * 1186 * Excel Function: 1187 * SUMIF(value1[,value2[, ...]],condition) 1188 * 1189 * @access public 1190 * @category Mathematical and Trigonometric Functions 1191 * @param mixed $arg,... Data values 1192 * @param string $condition The criteria that defines which cells will be summed. 1193 * @return float 1194 */ 1195 public static function SUMIF($aArgs, $condition, $sumArgs = array()) 1196 { 1197 $returnValue = 0; 1198 1199 $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); 1200 $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); 1201 if (empty($sumArgs)) { 1202 $sumArgs = $aArgs; 1203 } 1204 $condition = PHPExcel_Calculation_Functions::ifCondition($condition); 1205 // Loop through arguments 1206 foreach ($aArgs as $key => $arg) { 1207 if (!is_numeric($arg)) { 1208 $arg = str_replace('"', '""', $arg); 1209 $arg = PHPExcel_Calculation::wrapResult(strtoupper($arg)); 1210 } 1211 1212 $testCondition = '='.$arg.$condition; 1213 if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { 1214 // Is it a value within our criteria 1215 $returnValue += $sumArgs[$key]; 1216 } 1217 } 1218 1219 return $returnValue; 1220 } 1221 1222 1223 /** 1224 * SUMPRODUCT 1225 * 1226 * Excel Function: 1227 * SUMPRODUCT(value1[,value2[, ...]]) 1228 * 1229 * @access public 1230 * @category Mathematical and Trigonometric Functions 1231 * @param mixed $arg,... Data values 1232 * @return float 1233 */ 1234 public static function SUMPRODUCT() 1235 { 1236 $arrayList = func_get_args(); 1237 1238 $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); 1239 $wrkCellCount = count($wrkArray); 1240 1241 for ($i=0; $i< $wrkCellCount; ++$i) { 1242 if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) { 1243 $wrkArray[$i] = 0; 1244 } 1245 } 1246 1247 foreach ($arrayList as $matrixData) { 1248 $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); 1249 $count = count($array2); 1250 if ($wrkCellCount != $count) { 1251 return PHPExcel_Calculation_Functions::VALUE(); 1252 } 1253 1254 foreach ($array2 as $i => $val) { 1255 if ((!is_numeric($val)) || (is_string($val))) { 1256 $val = 0; 1257 } 1258 $wrkArray[$i] *= $val; 1259 } 1260 } 1261 1262 return array_sum($wrkArray); 1263 } 1264 1265 1266 /** 1267 * SUMSQ 1268 * 1269 * SUMSQ returns the sum of the squares of the arguments 1270 * 1271 * Excel Function: 1272 * SUMSQ(value1[,value2[, ...]]) 1273 * 1274 * @access public 1275 * @category Mathematical and Trigonometric Functions 1276 * @param mixed $arg,... Data values 1277 * @return float 1278 */ 1279 public static function SUMSQ() 1280 { 1281 $returnValue = 0; 1282 1283 // Loop through arguments 1284 foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { 1285 // Is it a numeric value? 1286 if ((is_numeric($arg)) && (!is_string($arg))) { 1287 $returnValue += ($arg * $arg); 1288 } 1289 } 1290 1291 return $returnValue; 1292 } 1293 1294 1295 /** 1296 * SUMX2MY2 1297 * 1298 * @param mixed[] $matrixData1 Matrix #1 1299 * @param mixed[] $matrixData2 Matrix #2 1300 * @return float 1301 */ 1302 public static function SUMX2MY2($matrixData1, $matrixData2) 1303 { 1304 $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); 1305 $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); 1306 $count = min(count($array1), count($array2)); 1307 1308 $result = 0; 1309 for ($i = 0; $i < $count; ++$i) { 1310 if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && 1311 ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { 1312 $result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]); 1313 } 1314 } 1315 1316 return $result; 1317 } 1318 1319 1320 /** 1321 * SUMX2PY2 1322 * 1323 * @param mixed[] $matrixData1 Matrix #1 1324 * @param mixed[] $matrixData2 Matrix #2 1325 * @return float 1326 */ 1327 public static function SUMX2PY2($matrixData1, $matrixData2) 1328 { 1329 $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); 1330 $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); 1331 $count = min(count($array1), count($array2)); 1332 1333 $result = 0; 1334 for ($i = 0; $i < $count; ++$i) { 1335 if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && 1336 ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { 1337 $result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]); 1338 } 1339 } 1340 1341 return $result; 1342 } 1343 1344 1345 /** 1346 * SUMXMY2 1347 * 1348 * @param mixed[] $matrixData1 Matrix #1 1349 * @param mixed[] $matrixData2 Matrix #2 1350 * @return float 1351 */ 1352 public static function SUMXMY2($matrixData1, $matrixData2) 1353 { 1354 $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); 1355 $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); 1356 $count = min(count($array1), count($array2)); 1357 1358 $result = 0; 1359 for ($i = 0; $i < $count; ++$i) { 1360 if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && 1361 ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { 1362 $result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]); 1363 } 1364 } 1365 1366 return $result; 1367 } 1368 1369 1370 /** 1371 * TRUNC 1372 * 1373 * Truncates value to the number of fractional digits by number_digits. 1374 * 1375 * @param float $value 1376 * @param int $digits 1377 * @return float Truncated value 1378 */ 1379 public static function TRUNC($value = 0, $digits = 0) 1380 { 1381 $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); 1382 $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); 1383 1384 // Validate parameters 1385 if ((!is_numeric($value)) || (!is_numeric($digits))) { 1386 return PHPExcel_Calculation_Functions::VALUE(); 1387 } 1388 $digits = floor($digits); 1389 1390 // Truncate 1391 $adjust = pow(10, $digits); 1392 1393 if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust), '0') < $adjust/10)) { 1394 return $value; 1395 } 1396 1397 return (intval($value * $adjust)) / $adjust; 1398 } 1399 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |