Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation; 4 5 use Complex\Complex; 6 use Complex\Exception as ComplexException; 7 use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ConvertUOM; 8 9 class Engineering 10 { 11 /** 12 * EULER. 13 */ 14 const EULER = 2.71828182845904523536; 15 16 /** 17 * parseComplex. 18 * 19 * Parses a complex number into its real and imaginary parts, and an I or J suffix 20 * 21 * @deprecated 2.0.0 No longer used by internal code. Please use the Complex\Complex class instead 22 * 23 * @param string $complexNumber The complex number 24 * 25 * @return mixed[] Indexed on "real", "imaginary" and "suffix" 26 */ 27 public static function parseComplex($complexNumber) 28 { 29 $complex = new Complex($complexNumber); 30 31 return [ 32 'real' => $complex->getReal(), 33 'imaginary' => $complex->getImaginary(), 34 'suffix' => $complex->getSuffix(), 35 ]; 36 } 37 38 /** 39 * Formats a number base string value with leading zeroes. 40 * 41 * @param string $xVal The "number" to pad 42 * @param int $places The length that we want to pad this value 43 * 44 * @return string The padded "number" 45 */ 46 private static function nbrConversionFormat($xVal, $places) 47 { 48 if ($places !== null) { 49 if (is_numeric($places)) { 50 $places = (int) $places; 51 } else { 52 return Functions::VALUE(); 53 } 54 if ($places < 0) { 55 return Functions::NAN(); 56 } 57 if (strlen($xVal) <= $places) { 58 return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); 59 } 60 61 return Functions::NAN(); 62 } 63 64 return substr($xVal, -10); 65 } 66 67 /** 68 * BESSELI. 69 * 70 * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated 71 * for purely imaginary arguments 72 * 73 * Excel Function: 74 * BESSELI(x,ord) 75 * 76 * @param float $x The value at which to evaluate the function. 77 * If x is nonnumeric, BESSELI returns the #VALUE! error value. 78 * @param int $ord The order of the Bessel function. 79 * If ord is not an integer, it is truncated. 80 * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. 81 * If $ord < 0, BESSELI returns the #NUM! error value. 82 * 83 * @return float|string Result, or a string containing an error 84 */ 85 public static function BESSELI($x, $ord) 86 { 87 $x = ($x === null) ? 0.0 : Functions::flattenSingleValue($x); 88 $ord = ($ord === null) ? 0.0 : Functions::flattenSingleValue($ord); 89 90 if ((is_numeric($x)) && (is_numeric($ord))) { 91 $ord = floor($ord); 92 if ($ord < 0) { 93 return Functions::NAN(); 94 } 95 96 if (abs($x) <= 30) { 97 $fResult = $fTerm = ($x / 2) ** $ord / MathTrig::FACT($ord); 98 $ordK = 1; 99 $fSqrX = ($x * $x) / 4; 100 do { 101 $fTerm *= $fSqrX; 102 $fTerm /= ($ordK * ($ordK + $ord)); 103 $fResult += $fTerm; 104 } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); 105 } else { 106 $f_2_PI = 2 * M_PI; 107 108 $fXAbs = abs($x); 109 $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs); 110 if (($ord & 1) && ($x < 0)) { 111 $fResult = -$fResult; 112 } 113 } 114 115 return (is_nan($fResult)) ? Functions::NAN() : $fResult; 116 } 117 118 return Functions::VALUE(); 119 } 120 121 /** 122 * BESSELJ. 123 * 124 * Returns the Bessel function 125 * 126 * Excel Function: 127 * BESSELJ(x,ord) 128 * 129 * @param float $x The value at which to evaluate the function. 130 * If x is nonnumeric, BESSELJ returns the #VALUE! error value. 131 * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. 132 * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. 133 * If $ord < 0, BESSELJ returns the #NUM! error value. 134 * 135 * @return float|string Result, or a string containing an error 136 */ 137 public static function BESSELJ($x, $ord) 138 { 139 $x = ($x === null) ? 0.0 : Functions::flattenSingleValue($x); 140 $ord = ($ord === null) ? 0.0 : Functions::flattenSingleValue($ord); 141 142 if ((is_numeric($x)) && (is_numeric($ord))) { 143 $ord = floor($ord); 144 if ($ord < 0) { 145 return Functions::NAN(); 146 } 147 148 $fResult = 0; 149 if (abs($x) <= 30) { 150 $fResult = $fTerm = ($x / 2) ** $ord / MathTrig::FACT($ord); 151 $ordK = 1; 152 $fSqrX = ($x * $x) / -4; 153 do { 154 $fTerm *= $fSqrX; 155 $fTerm /= ($ordK * ($ordK + $ord)); 156 $fResult += $fTerm; 157 } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); 158 } else { 159 $f_PI_DIV_2 = M_PI / 2; 160 $f_PI_DIV_4 = M_PI / 4; 161 162 $fXAbs = abs($x); 163 $fResult = sqrt(Functions::M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4); 164 if (($ord & 1) && ($x < 0)) { 165 $fResult = -$fResult; 166 } 167 } 168 169 return (is_nan($fResult)) ? Functions::NAN() : $fResult; 170 } 171 172 return Functions::VALUE(); 173 } 174 175 private static function besselK0($fNum) 176 { 177 if ($fNum <= 2) { 178 $fNum2 = $fNum * 0.5; 179 $y = ($fNum2 * $fNum2); 180 $fRet = -log($fNum2) * self::BESSELI($fNum, 0) + 181 (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * 182 (0.10750e-3 + $y * 0.74e-5)))))); 183 } else { 184 $y = 2 / $fNum; 185 $fRet = exp(-$fNum) / sqrt($fNum) * 186 (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * 187 (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); 188 } 189 190 return $fRet; 191 } 192 193 private static function besselK1($fNum) 194 { 195 if ($fNum <= 2) { 196 $fNum2 = $fNum * 0.5; 197 $y = ($fNum2 * $fNum2); 198 $fRet = log($fNum2) * self::BESSELI($fNum, 1) + 199 (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * 200 (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum; 201 } else { 202 $y = 2 / $fNum; 203 $fRet = exp(-$fNum) / sqrt($fNum) * 204 (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * 205 (0.325614e-2 + $y * (-0.68245e-3))))))); 206 } 207 208 return $fRet; 209 } 210 211 /** 212 * BESSELK. 213 * 214 * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated 215 * for purely imaginary arguments. 216 * 217 * Excel Function: 218 * BESSELK(x,ord) 219 * 220 * @param float $x The value at which to evaluate the function. 221 * If x is nonnumeric, BESSELK returns the #VALUE! error value. 222 * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. 223 * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. 224 * If $ord < 0, BESSELK returns the #NUM! error value. 225 * 226 * @return float|string Result, or a string containing an error 227 */ 228 public static function BESSELK($x, $ord) 229 { 230 $x = ($x === null) ? 0.0 : Functions::flattenSingleValue($x); 231 $ord = ($ord === null) ? 0.0 : Functions::flattenSingleValue($ord); 232 233 if ((is_numeric($x)) && (is_numeric($ord))) { 234 if (($ord < 0) || ($x == 0.0)) { 235 return Functions::NAN(); 236 } 237 238 switch (floor($ord)) { 239 case 0: 240 $fBk = self::besselK0($x); 241 242 break; 243 case 1: 244 $fBk = self::besselK1($x); 245 246 break; 247 default: 248 $fTox = 2 / $x; 249 $fBkm = self::besselK0($x); 250 $fBk = self::besselK1($x); 251 for ($n = 1; $n < $ord; ++$n) { 252 $fBkp = $fBkm + $n * $fTox * $fBk; 253 $fBkm = $fBk; 254 $fBk = $fBkp; 255 } 256 } 257 258 return (is_nan($fBk)) ? Functions::NAN() : $fBk; 259 } 260 261 return Functions::VALUE(); 262 } 263 264 private static function besselY0($fNum) 265 { 266 if ($fNum < 8.0) { 267 $y = ($fNum * $fNum); 268 $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); 269 $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); 270 $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum); 271 } else { 272 $z = 8.0 / $fNum; 273 $y = ($z * $z); 274 $xx = $fNum - 0.785398164; 275 $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); 276 $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); 277 $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2); 278 } 279 280 return $fRet; 281 } 282 283 private static function besselY1($fNum) 284 { 285 if ($fNum < 8.0) { 286 $y = ($fNum * $fNum); 287 $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * 288 (-0.4237922726e7 + $y * 0.8511937935e4))))); 289 $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * 290 (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); 291 $fRet = $f1 / $f2 + 0.636619772 * (self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum); 292 } else { 293 $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491); 294 } 295 296 return $fRet; 297 } 298 299 /** 300 * BESSELY. 301 * 302 * Returns the Bessel function, which is also called the Weber function or the Neumann function. 303 * 304 * Excel Function: 305 * BESSELY(x,ord) 306 * 307 * @param float $x The value at which to evaluate the function. 308 * If x is nonnumeric, BESSELK returns the #VALUE! error value. 309 * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. 310 * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. 311 * If $ord < 0, BESSELK returns the #NUM! error value. 312 * 313 * @return float|string Result, or a string containing an error 314 */ 315 public static function BESSELY($x, $ord) 316 { 317 $x = ($x === null) ? 0.0 : Functions::flattenSingleValue($x); 318 $ord = ($ord === null) ? 0.0 : Functions::flattenSingleValue($ord); 319 320 if ((is_numeric($x)) && (is_numeric($ord))) { 321 if (($ord < 0) || ($x == 0.0)) { 322 return Functions::NAN(); 323 } 324 325 switch (floor($ord)) { 326 case 0: 327 $fBy = self::besselY0($x); 328 329 break; 330 case 1: 331 $fBy = self::besselY1($x); 332 333 break; 334 default: 335 $fTox = 2 / $x; 336 $fBym = self::besselY0($x); 337 $fBy = self::besselY1($x); 338 for ($n = 1; $n < $ord; ++$n) { 339 $fByp = $n * $fTox * $fBy - $fBym; 340 $fBym = $fBy; 341 $fBy = $fByp; 342 } 343 } 344 345 return (is_nan($fBy)) ? Functions::NAN() : $fBy; 346 } 347 348 return Functions::VALUE(); 349 } 350 351 /** 352 * BINTODEC. 353 * 354 * Return a binary value as decimal. 355 * 356 * Excel Function: 357 * BIN2DEC(x) 358 * 359 * @param string $x The binary number (as a string) that you want to convert. The number 360 * cannot contain more than 10 characters (10 bits). The most significant 361 * bit of number is the sign bit. The remaining 9 bits are magnitude bits. 362 * Negative numbers are represented using two's-complement notation. 363 * If number is not a valid binary number, or if number contains more than 364 * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. 365 * 366 * @return string 367 */ 368 public static function BINTODEC($x) 369 { 370 $x = Functions::flattenSingleValue($x); 371 372 if (is_bool($x)) { 373 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 374 $x = (int) $x; 375 } else { 376 return Functions::VALUE(); 377 } 378 } 379 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { 380 $x = floor($x); 381 } 382 $x = (string) $x; 383 if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { 384 return Functions::NAN(); 385 } 386 if (strlen($x) > 10) { 387 return Functions::NAN(); 388 } elseif (strlen($x) == 10) { 389 // Two's Complement 390 $x = substr($x, -9); 391 392 return '-' . (512 - bindec($x)); 393 } 394 395 return bindec($x); 396 } 397 398 /** 399 * BINTOHEX. 400 * 401 * Return a binary value as hex. 402 * 403 * Excel Function: 404 * BIN2HEX(x[,places]) 405 * 406 * @param string $x The binary number (as a string) that you want to convert. The number 407 * cannot contain more than 10 characters (10 bits). The most significant 408 * bit of number is the sign bit. The remaining 9 bits are magnitude bits. 409 * Negative numbers are represented using two's-complement notation. 410 * If number is not a valid binary number, or if number contains more than 411 * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. 412 * @param int $places The number of characters to use. If places is omitted, BIN2HEX uses the 413 * minimum number of characters necessary. Places is useful for padding the 414 * return value with leading 0s (zeros). 415 * If places is not an integer, it is truncated. 416 * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. 417 * If places is negative, BIN2HEX returns the #NUM! error value. 418 * 419 * @return string 420 */ 421 public static function BINTOHEX($x, $places = null) 422 { 423 $x = Functions::flattenSingleValue($x); 424 $places = Functions::flattenSingleValue($places); 425 426 // Argument X 427 if (is_bool($x)) { 428 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 429 $x = (int) $x; 430 } else { 431 return Functions::VALUE(); 432 } 433 } 434 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { 435 $x = floor($x); 436 } 437 $x = (string) $x; 438 if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { 439 return Functions::NAN(); 440 } 441 if (strlen($x) > 10) { 442 return Functions::NAN(); 443 } elseif (strlen($x) == 10) { 444 // Two's Complement 445 return str_repeat('F', 8) . substr(strtoupper(dechex(bindec(substr($x, -9)))), -2); 446 } 447 $hexVal = (string) strtoupper(dechex(bindec($x))); 448 449 return self::nbrConversionFormat($hexVal, $places); 450 } 451 452 /** 453 * BINTOOCT. 454 * 455 * Return a binary value as octal. 456 * 457 * Excel Function: 458 * BIN2OCT(x[,places]) 459 * 460 * @param string $x The binary number (as a string) that you want to convert. The number 461 * cannot contain more than 10 characters (10 bits). The most significant 462 * bit of number is the sign bit. The remaining 9 bits are magnitude bits. 463 * Negative numbers are represented using two's-complement notation. 464 * If number is not a valid binary number, or if number contains more than 465 * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. 466 * @param int $places The number of characters to use. If places is omitted, BIN2OCT uses the 467 * minimum number of characters necessary. Places is useful for padding the 468 * return value with leading 0s (zeros). 469 * If places is not an integer, it is truncated. 470 * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. 471 * If places is negative, BIN2OCT returns the #NUM! error value. 472 * 473 * @return string 474 */ 475 public static function BINTOOCT($x, $places = null) 476 { 477 $x = Functions::flattenSingleValue($x); 478 $places = Functions::flattenSingleValue($places); 479 480 if (is_bool($x)) { 481 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 482 $x = (int) $x; 483 } else { 484 return Functions::VALUE(); 485 } 486 } 487 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { 488 $x = floor($x); 489 } 490 $x = (string) $x; 491 if (strlen($x) > preg_match_all('/[01]/', $x, $out)) { 492 return Functions::NAN(); 493 } 494 if (strlen($x) > 10) { 495 return Functions::NAN(); 496 } elseif (strlen($x) == 10) { 497 // Two's Complement 498 return str_repeat('7', 7) . substr(strtoupper(decoct(bindec(substr($x, -9)))), -3); 499 } 500 $octVal = (string) decoct(bindec($x)); 501 502 return self::nbrConversionFormat($octVal, $places); 503 } 504 505 /** 506 * DECTOBIN. 507 * 508 * Return a decimal value as binary. 509 * 510 * Excel Function: 511 * DEC2BIN(x[,places]) 512 * 513 * @param string $x The decimal integer you want to convert. If number is negative, 514 * valid place values are ignored and DEC2BIN returns a 10-character 515 * (10-bit) binary number in which the most significant bit is the sign 516 * bit. The remaining 9 bits are magnitude bits. Negative numbers are 517 * represented using two's-complement notation. 518 * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error 519 * value. 520 * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. 521 * If DEC2BIN requires more than places characters, it returns the #NUM! 522 * error value. 523 * @param int $places The number of characters to use. If places is omitted, DEC2BIN uses 524 * the minimum number of characters necessary. Places is useful for 525 * padding the return value with leading 0s (zeros). 526 * If places is not an integer, it is truncated. 527 * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. 528 * If places is zero or negative, DEC2BIN returns the #NUM! error value. 529 * 530 * @return string 531 */ 532 public static function DECTOBIN($x, $places = null) 533 { 534 $x = Functions::flattenSingleValue($x); 535 $places = Functions::flattenSingleValue($places); 536 537 if (is_bool($x)) { 538 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 539 $x = (int) $x; 540 } else { 541 return Functions::VALUE(); 542 } 543 } 544 $x = (string) $x; 545 if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { 546 return Functions::VALUE(); 547 } 548 549 $x = (string) floor($x); 550 if ($x < -512 || $x > 511) { 551 return Functions::NAN(); 552 } 553 554 $r = decbin($x); 555 // Two's Complement 556 $r = substr($r, -10); 557 if (strlen($r) >= 11) { 558 return Functions::NAN(); 559 } 560 561 return self::nbrConversionFormat($r, $places); 562 } 563 564 /** 565 * DECTOHEX. 566 * 567 * Return a decimal value as hex. 568 * 569 * Excel Function: 570 * DEC2HEX(x[,places]) 571 * 572 * @param string $x The decimal integer you want to convert. If number is negative, 573 * places is ignored and DEC2HEX returns a 10-character (40-bit) 574 * hexadecimal number in which the most significant bit is the sign 575 * bit. The remaining 39 bits are magnitude bits. Negative numbers 576 * are represented using two's-complement notation. 577 * If number < -549,755,813,888 or if number > 549,755,813,887, 578 * DEC2HEX returns the #NUM! error value. 579 * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. 580 * If DEC2HEX requires more than places characters, it returns the 581 * #NUM! error value. 582 * @param int $places The number of characters to use. If places is omitted, DEC2HEX uses 583 * the minimum number of characters necessary. Places is useful for 584 * padding the return value with leading 0s (zeros). 585 * If places is not an integer, it is truncated. 586 * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. 587 * If places is zero or negative, DEC2HEX returns the #NUM! error value. 588 * 589 * @return string 590 */ 591 public static function DECTOHEX($x, $places = null) 592 { 593 $x = Functions::flattenSingleValue($x); 594 $places = Functions::flattenSingleValue($places); 595 596 if (is_bool($x)) { 597 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 598 $x = (int) $x; 599 } else { 600 return Functions::VALUE(); 601 } 602 } 603 $x = (string) $x; 604 if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { 605 return Functions::VALUE(); 606 } 607 $x = (string) floor($x); 608 $r = strtoupper(dechex($x)); 609 if (strlen($r) == 8) { 610 // Two's Complement 611 $r = 'FF' . $r; 612 } 613 614 return self::nbrConversionFormat($r, $places); 615 } 616 617 /** 618 * DECTOOCT. 619 * 620 * Return an decimal value as octal. 621 * 622 * Excel Function: 623 * DEC2OCT(x[,places]) 624 * 625 * @param string $x The decimal integer you want to convert. If number is negative, 626 * places is ignored and DEC2OCT returns a 10-character (30-bit) 627 * octal number in which the most significant bit is the sign bit. 628 * The remaining 29 bits are magnitude bits. Negative numbers are 629 * represented using two's-complement notation. 630 * If number < -536,870,912 or if number > 536,870,911, DEC2OCT 631 * returns the #NUM! error value. 632 * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. 633 * If DEC2OCT requires more than places characters, it returns the 634 * #NUM! error value. 635 * @param int $places The number of characters to use. If places is omitted, DEC2OCT uses 636 * the minimum number of characters necessary. Places is useful for 637 * padding the return value with leading 0s (zeros). 638 * If places is not an integer, it is truncated. 639 * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. 640 * If places is zero or negative, DEC2OCT returns the #NUM! error value. 641 * 642 * @return string 643 */ 644 public static function DECTOOCT($x, $places = null) 645 { 646 $xorig = $x; 647 $x = Functions::flattenSingleValue($x); 648 $places = Functions::flattenSingleValue($places); 649 650 if (is_bool($x)) { 651 if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { 652 $x = (int) $x; 653 } else { 654 return Functions::VALUE(); 655 } 656 } 657 $x = (string) $x; 658 if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { 659 return Functions::VALUE(); 660 } 661 $x = (string) floor($x); 662 $r = decoct($x); 663 if (strlen($r) == 11) { 664 // Two's Complement 665 $r = substr($r, -10); 666 } 667 668 return self::nbrConversionFormat($r, $places); 669 } 670 671 /** 672 * HEXTOBIN. 673 * 674 * Return a hex value as binary. 675 * 676 * Excel Function: 677 * HEX2BIN(x[,places]) 678 * 679 * @param string $x the hexadecimal number you want to convert. 680 * Number cannot contain more than 10 characters. 681 * The most significant bit of number is the sign bit (40th bit from the right). 682 * The remaining 9 bits are magnitude bits. 683 * Negative numbers are represented using two's-complement notation. 684 * If number is negative, HEX2BIN ignores places and returns a 10-character binary number. 685 * If number is negative, it cannot be less than FFFFFFFE00, 686 * and if number is positive, it cannot be greater than 1FF. 687 * If number is not a valid hexadecimal number, HEX2BIN returns the #NUM! error value. 688 * If HEX2BIN requires more than places characters, it returns the #NUM! error value. 689 * @param int $places The number of characters to use. If places is omitted, 690 * HEX2BIN uses the minimum number of characters necessary. Places 691 * is useful for padding the return value with leading 0s (zeros). 692 * If places is not an integer, it is truncated. 693 * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. 694 * If places is negative, HEX2BIN returns the #NUM! error value. 695 * 696 * @return string 697 */ 698 public static function HEXTOBIN($x, $places = null) 699 { 700 $x = Functions::flattenSingleValue($x); 701 $places = Functions::flattenSingleValue($places); 702 703 if (is_bool($x)) { 704 return Functions::VALUE(); 705 } 706 $x = (string) $x; 707 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { 708 return Functions::NAN(); 709 } 710 711 return self::DECTOBIN(self::HEXTODEC($x), $places); 712 } 713 714 /** 715 * HEXTODEC. 716 * 717 * Return a hex value as decimal. 718 * 719 * Excel Function: 720 * HEX2DEC(x) 721 * 722 * @param string $x The hexadecimal number you want to convert. This number cannot 723 * contain more than 10 characters (40 bits). The most significant 724 * bit of number is the sign bit. The remaining 39 bits are magnitude 725 * bits. Negative numbers are represented using two's-complement 726 * notation. 727 * If number is not a valid hexadecimal number, HEX2DEC returns the 728 * #NUM! error value. 729 * 730 * @return string 731 */ 732 public static function HEXTODEC($x) 733 { 734 $x = Functions::flattenSingleValue($x); 735 736 if (is_bool($x)) { 737 return Functions::VALUE(); 738 } 739 $x = (string) $x; 740 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { 741 return Functions::NAN(); 742 } 743 744 if (strlen($x) > 10) { 745 return Functions::NAN(); 746 } 747 748 $binX = ''; 749 foreach (str_split($x) as $char) { 750 $binX .= str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT); 751 } 752 if (strlen($binX) == 40 && $binX[0] == '1') { 753 for ($i = 0; $i < 40; ++$i) { 754 $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); 755 } 756 757 return (bindec($binX) + 1) * -1; 758 } 759 760 return bindec($binX); 761 } 762 763 /** 764 * HEXTOOCT. 765 * 766 * Return a hex value as octal. 767 * 768 * Excel Function: 769 * HEX2OCT(x[,places]) 770 * 771 * @param string $x The hexadecimal number you want to convert. Number cannot 772 * contain more than 10 characters. The most significant bit of 773 * number is the sign bit. The remaining 39 bits are magnitude 774 * bits. Negative numbers are represented using two's-complement 775 * notation. 776 * If number is negative, HEX2OCT ignores places and returns a 777 * 10-character octal number. 778 * If number is negative, it cannot be less than FFE0000000, and 779 * if number is positive, it cannot be greater than 1FFFFFFF. 780 * If number is not a valid hexadecimal number, HEX2OCT returns 781 * the #NUM! error value. 782 * If HEX2OCT requires more than places characters, it returns 783 * the #NUM! error value. 784 * @param int $places The number of characters to use. If places is omitted, HEX2OCT 785 * uses the minimum number of characters necessary. Places is 786 * useful for padding the return value with leading 0s (zeros). 787 * If places is not an integer, it is truncated. 788 * If places is nonnumeric, HEX2OCT returns the #VALUE! error 789 * value. 790 * If places is negative, HEX2OCT returns the #NUM! error value. 791 * 792 * @return string 793 */ 794 public static function HEXTOOCT($x, $places = null) 795 { 796 $x = Functions::flattenSingleValue($x); 797 $places = Functions::flattenSingleValue($places); 798 799 if (is_bool($x)) { 800 return Functions::VALUE(); 801 } 802 $x = (string) $x; 803 if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { 804 return Functions::NAN(); 805 } 806 807 $decimal = self::HEXTODEC($x); 808 if ($decimal < -536870912 || $decimal > 536870911) { 809 return Functions::NAN(); 810 } 811 812 return self::DECTOOCT($decimal, $places); 813 } 814 815 /** 816 * OCTTOBIN. 817 * 818 * Return an octal value as binary. 819 * 820 * Excel Function: 821 * OCT2BIN(x[,places]) 822 * 823 * @param string $x The octal number you want to convert. Number may not 824 * contain more than 10 characters. The most significant 825 * bit of number is the sign bit. The remaining 29 bits 826 * are magnitude bits. Negative numbers are represented 827 * using two's-complement notation. 828 * If number is negative, OCT2BIN ignores places and returns 829 * a 10-character binary number. 830 * If number is negative, it cannot be less than 7777777000, 831 * and if number is positive, it cannot be greater than 777. 832 * If number is not a valid octal number, OCT2BIN returns 833 * the #NUM! error value. 834 * If OCT2BIN requires more than places characters, it 835 * returns the #NUM! error value. 836 * @param int $places The number of characters to use. If places is omitted, 837 * OCT2BIN uses the minimum number of characters necessary. 838 * Places is useful for padding the return value with 839 * leading 0s (zeros). 840 * If places is not an integer, it is truncated. 841 * If places is nonnumeric, OCT2BIN returns the #VALUE! 842 * error value. 843 * If places is negative, OCT2BIN returns the #NUM! error 844 * value. 845 * 846 * @return string 847 */ 848 public static function OCTTOBIN($x, $places = null) 849 { 850 $x = Functions::flattenSingleValue($x); 851 $places = Functions::flattenSingleValue($places); 852 853 if (is_bool($x)) { 854 return Functions::VALUE(); 855 } 856 $x = (string) $x; 857 if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { 858 return Functions::NAN(); 859 } 860 861 return self::DECTOBIN(self::OCTTODEC($x), $places); 862 } 863 864 /** 865 * OCTTODEC. 866 * 867 * Return an octal value as decimal. 868 * 869 * Excel Function: 870 * OCT2DEC(x) 871 * 872 * @param string $x The octal number you want to convert. Number may not contain 873 * more than 10 octal characters (30 bits). The most significant 874 * bit of number is the sign bit. The remaining 29 bits are 875 * magnitude bits. Negative numbers are represented using 876 * two's-complement notation. 877 * If number is not a valid octal number, OCT2DEC returns the 878 * #NUM! error value. 879 * 880 * @return string 881 */ 882 public static function OCTTODEC($x) 883 { 884 $x = Functions::flattenSingleValue($x); 885 886 if (is_bool($x)) { 887 return Functions::VALUE(); 888 } 889 $x = (string) $x; 890 if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { 891 return Functions::NAN(); 892 } 893 $binX = ''; 894 foreach (str_split($x) as $char) { 895 $binX .= str_pad(decbin((int) $char), 3, '0', STR_PAD_LEFT); 896 } 897 if (strlen($binX) == 30 && $binX[0] == '1') { 898 for ($i = 0; $i < 30; ++$i) { 899 $binX[$i] = ($binX[$i] == '1' ? '0' : '1'); 900 } 901 902 return (bindec($binX) + 1) * -1; 903 } 904 905 return bindec($binX); 906 } 907 908 /** 909 * OCTTOHEX. 910 * 911 * Return an octal value as hex. 912 * 913 * Excel Function: 914 * OCT2HEX(x[,places]) 915 * 916 * @param string $x The octal number you want to convert. Number may not contain 917 * more than 10 octal characters (30 bits). The most significant 918 * bit of number is the sign bit. The remaining 29 bits are 919 * magnitude bits. Negative numbers are represented using 920 * two's-complement notation. 921 * If number is negative, OCT2HEX ignores places and returns a 922 * 10-character hexadecimal number. 923 * If number is not a valid octal number, OCT2HEX returns the 924 * #NUM! error value. 925 * If OCT2HEX requires more than places characters, it returns 926 * the #NUM! error value. 927 * @param int $places The number of characters to use. If places is omitted, OCT2HEX 928 * uses the minimum number of characters necessary. Places is useful 929 * for padding the return value with leading 0s (zeros). 930 * If places is not an integer, it is truncated. 931 * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. 932 * If places is negative, OCT2HEX returns the #NUM! error value. 933 * 934 * @return string 935 */ 936 public static function OCTTOHEX($x, $places = null) 937 { 938 $x = Functions::flattenSingleValue($x); 939 $places = Functions::flattenSingleValue($places); 940 941 if (is_bool($x)) { 942 return Functions::VALUE(); 943 } 944 $x = (string) $x; 945 if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { 946 return Functions::NAN(); 947 } 948 $hexVal = strtoupper(dechex(self::OCTTODEC($x))); 949 950 return self::nbrConversionFormat($hexVal, $places); 951 } 952 953 /** 954 * COMPLEX. 955 * 956 * Converts real and imaginary coefficients into a complex number of the form x +/- yi or x +/- yj. 957 * 958 * Excel Function: 959 * COMPLEX(realNumber,imaginary[,suffix]) 960 * 961 * @param float $realNumber the real coefficient of the complex number 962 * @param float $imaginary the imaginary coefficient of the complex number 963 * @param string $suffix The suffix for the imaginary component of the complex number. 964 * If omitted, the suffix is assumed to be "i". 965 * 966 * @return string 967 */ 968 public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') 969 { 970 $realNumber = ($realNumber === null) ? 0.0 : Functions::flattenSingleValue($realNumber); 971 $imaginary = ($imaginary === null) ? 0.0 : Functions::flattenSingleValue($imaginary); 972 $suffix = ($suffix === null) ? 'i' : Functions::flattenSingleValue($suffix); 973 974 if ( 975 ((is_numeric($realNumber)) && (is_numeric($imaginary))) && 976 (($suffix == 'i') || ($suffix == 'j') || ($suffix == '')) 977 ) { 978 $complex = new Complex($realNumber, $imaginary, $suffix); 979 980 return (string) $complex; 981 } 982 983 return Functions::VALUE(); 984 } 985 986 /** 987 * IMAGINARY. 988 * 989 * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. 990 * 991 * Excel Function: 992 * IMAGINARY(complexNumber) 993 * 994 * @param string $complexNumber the complex number for which you want the imaginary 995 * coefficient 996 * 997 * @return float 998 */ 999 public static function IMAGINARY($complexNumber) 1000 { 1001 $complexNumber = Functions::flattenSingleValue($complexNumber); 1002 1003 return (new Complex($complexNumber))->getImaginary(); 1004 } 1005 1006 /** 1007 * IMREAL. 1008 * 1009 * Returns the real coefficient of a complex number in x + yi or x + yj text format. 1010 * 1011 * Excel Function: 1012 * IMREAL(complexNumber) 1013 * 1014 * @param string $complexNumber the complex number for which you want the real coefficient 1015 * 1016 * @return float 1017 */ 1018 public static function IMREAL($complexNumber) 1019 { 1020 $complexNumber = Functions::flattenSingleValue($complexNumber); 1021 1022 return (new Complex($complexNumber))->getReal(); 1023 } 1024 1025 /** 1026 * IMABS. 1027 * 1028 * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. 1029 * 1030 * Excel Function: 1031 * IMABS(complexNumber) 1032 * 1033 * @param string $complexNumber the complex number for which you want the absolute value 1034 * 1035 * @return float 1036 */ 1037 public static function IMABS($complexNumber) 1038 { 1039 $complexNumber = Functions::flattenSingleValue($complexNumber); 1040 1041 return (new Complex($complexNumber))->abs(); 1042 } 1043 1044 /** 1045 * IMARGUMENT. 1046 * 1047 * Returns the argument theta of a complex number, i.e. the angle in radians from the real 1048 * axis to the representation of the number in polar coordinates. 1049 * 1050 * Excel Function: 1051 * IMARGUMENT(complexNumber) 1052 * 1053 * @param string $complexNumber the complex number for which you want the argument theta 1054 * 1055 * @return float|string 1056 */ 1057 public static function IMARGUMENT($complexNumber) 1058 { 1059 $complexNumber = Functions::flattenSingleValue($complexNumber); 1060 1061 $complex = new Complex($complexNumber); 1062 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { 1063 return Functions::DIV0(); 1064 } 1065 1066 return $complex->argument(); 1067 } 1068 1069 /** 1070 * IMCONJUGATE. 1071 * 1072 * Returns the complex conjugate of a complex number in x + yi or x + yj text format. 1073 * 1074 * Excel Function: 1075 * IMCONJUGATE(complexNumber) 1076 * 1077 * @param string $complexNumber the complex number for which you want the conjugate 1078 * 1079 * @return string 1080 */ 1081 public static function IMCONJUGATE($complexNumber) 1082 { 1083 $complexNumber = Functions::flattenSingleValue($complexNumber); 1084 1085 return (string) (new Complex($complexNumber))->conjugate(); 1086 } 1087 1088 /** 1089 * IMCOS. 1090 * 1091 * Returns the cosine of a complex number in x + yi or x + yj text format. 1092 * 1093 * Excel Function: 1094 * IMCOS(complexNumber) 1095 * 1096 * @param string $complexNumber the complex number for which you want the cosine 1097 * 1098 * @return float|string 1099 */ 1100 public static function IMCOS($complexNumber) 1101 { 1102 $complexNumber = Functions::flattenSingleValue($complexNumber); 1103 1104 return (string) (new Complex($complexNumber))->cos(); 1105 } 1106 1107 /** 1108 * IMCOSH. 1109 * 1110 * Returns the hyperbolic cosine of a complex number in x + yi or x + yj text format. 1111 * 1112 * Excel Function: 1113 * IMCOSH(complexNumber) 1114 * 1115 * @param string $complexNumber the complex number for which you want the hyperbolic cosine 1116 * 1117 * @return float|string 1118 */ 1119 public static function IMCOSH($complexNumber) 1120 { 1121 $complexNumber = Functions::flattenSingleValue($complexNumber); 1122 1123 return (string) (new Complex($complexNumber))->cosh(); 1124 } 1125 1126 /** 1127 * IMCOT. 1128 * 1129 * Returns the cotangent of a complex number in x + yi or x + yj text format. 1130 * 1131 * Excel Function: 1132 * IMCOT(complexNumber) 1133 * 1134 * @param string $complexNumber the complex number for which you want the cotangent 1135 * 1136 * @return float|string 1137 */ 1138 public static function IMCOT($complexNumber) 1139 { 1140 $complexNumber = Functions::flattenSingleValue($complexNumber); 1141 1142 return (string) (new Complex($complexNumber))->cot(); 1143 } 1144 1145 /** 1146 * IMCSC. 1147 * 1148 * Returns the cosecant of a complex number in x + yi or x + yj text format. 1149 * 1150 * Excel Function: 1151 * IMCSC(complexNumber) 1152 * 1153 * @param string $complexNumber the complex number for which you want the cosecant 1154 * 1155 * @return float|string 1156 */ 1157 public static function IMCSC($complexNumber) 1158 { 1159 $complexNumber = Functions::flattenSingleValue($complexNumber); 1160 1161 return (string) (new Complex($complexNumber))->csc(); 1162 } 1163 1164 /** 1165 * IMCSCH. 1166 * 1167 * Returns the hyperbolic cosecant of a complex number in x + yi or x + yj text format. 1168 * 1169 * Excel Function: 1170 * IMCSCH(complexNumber) 1171 * 1172 * @param string $complexNumber the complex number for which you want the hyperbolic cosecant 1173 * 1174 * @return float|string 1175 */ 1176 public static function IMCSCH($complexNumber) 1177 { 1178 $complexNumber = Functions::flattenSingleValue($complexNumber); 1179 1180 return (string) (new Complex($complexNumber))->csch(); 1181 } 1182 1183 /** 1184 * IMSIN. 1185 * 1186 * Returns the sine of a complex number in x + yi or x + yj text format. 1187 * 1188 * Excel Function: 1189 * IMSIN(complexNumber) 1190 * 1191 * @param string $complexNumber the complex number for which you want the sine 1192 * 1193 * @return float|string 1194 */ 1195 public static function IMSIN($complexNumber) 1196 { 1197 $complexNumber = Functions::flattenSingleValue($complexNumber); 1198 1199 return (string) (new Complex($complexNumber))->sin(); 1200 } 1201 1202 /** 1203 * IMSINH. 1204 * 1205 * Returns the hyperbolic sine of a complex number in x + yi or x + yj text format. 1206 * 1207 * Excel Function: 1208 * IMSINH(complexNumber) 1209 * 1210 * @param string $complexNumber the complex number for which you want the hyperbolic sine 1211 * 1212 * @return float|string 1213 */ 1214 public static function IMSINH($complexNumber) 1215 { 1216 $complexNumber = Functions::flattenSingleValue($complexNumber); 1217 1218 return (string) (new Complex($complexNumber))->sinh(); 1219 } 1220 1221 /** 1222 * IMSEC. 1223 * 1224 * Returns the secant of a complex number in x + yi or x + yj text format. 1225 * 1226 * Excel Function: 1227 * IMSEC(complexNumber) 1228 * 1229 * @param string $complexNumber the complex number for which you want the secant 1230 * 1231 * @return float|string 1232 */ 1233 public static function IMSEC($complexNumber) 1234 { 1235 $complexNumber = Functions::flattenSingleValue($complexNumber); 1236 1237 return (string) (new Complex($complexNumber))->sec(); 1238 } 1239 1240 /** 1241 * IMSECH. 1242 * 1243 * Returns the hyperbolic secant of a complex number in x + yi or x + yj text format. 1244 * 1245 * Excel Function: 1246 * IMSECH(complexNumber) 1247 * 1248 * @param string $complexNumber the complex number for which you want the hyperbolic secant 1249 * 1250 * @return float|string 1251 */ 1252 public static function IMSECH($complexNumber) 1253 { 1254 $complexNumber = Functions::flattenSingleValue($complexNumber); 1255 1256 return (string) (new Complex($complexNumber))->sech(); 1257 } 1258 1259 /** 1260 * IMTAN. 1261 * 1262 * Returns the tangent of a complex number in x + yi or x + yj text format. 1263 * 1264 * Excel Function: 1265 * IMTAN(complexNumber) 1266 * 1267 * @param string $complexNumber the complex number for which you want the tangent 1268 * 1269 * @return float|string 1270 */ 1271 public static function IMTAN($complexNumber) 1272 { 1273 $complexNumber = Functions::flattenSingleValue($complexNumber); 1274 1275 return (string) (new Complex($complexNumber))->tan(); 1276 } 1277 1278 /** 1279 * IMSQRT. 1280 * 1281 * Returns the square root of a complex number in x + yi or x + yj text format. 1282 * 1283 * Excel Function: 1284 * IMSQRT(complexNumber) 1285 * 1286 * @param string $complexNumber the complex number for which you want the square root 1287 * 1288 * @return string 1289 */ 1290 public static function IMSQRT($complexNumber) 1291 { 1292 $complexNumber = Functions::flattenSingleValue($complexNumber); 1293 1294 $theta = self::IMARGUMENT($complexNumber); 1295 if ($theta === Functions::DIV0()) { 1296 return '0'; 1297 } 1298 1299 return (string) (new Complex($complexNumber))->sqrt(); 1300 } 1301 1302 /** 1303 * IMLN. 1304 * 1305 * Returns the natural logarithm of a complex number in x + yi or x + yj text format. 1306 * 1307 * Excel Function: 1308 * IMLN(complexNumber) 1309 * 1310 * @param string $complexNumber the complex number for which you want the natural logarithm 1311 * 1312 * @return string 1313 */ 1314 public static function IMLN($complexNumber) 1315 { 1316 $complexNumber = Functions::flattenSingleValue($complexNumber); 1317 1318 $complex = new Complex($complexNumber); 1319 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { 1320 return Functions::NAN(); 1321 } 1322 1323 return (string) (new Complex($complexNumber))->ln(); 1324 } 1325 1326 /** 1327 * IMLOG10. 1328 * 1329 * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. 1330 * 1331 * Excel Function: 1332 * IMLOG10(complexNumber) 1333 * 1334 * @param string $complexNumber the complex number for which you want the common logarithm 1335 * 1336 * @return string 1337 */ 1338 public static function IMLOG10($complexNumber) 1339 { 1340 $complexNumber = Functions::flattenSingleValue($complexNumber); 1341 1342 $complex = new Complex($complexNumber); 1343 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { 1344 return Functions::NAN(); 1345 } 1346 1347 return (string) (new Complex($complexNumber))->log10(); 1348 } 1349 1350 /** 1351 * IMLOG2. 1352 * 1353 * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. 1354 * 1355 * Excel Function: 1356 * IMLOG2(complexNumber) 1357 * 1358 * @param string $complexNumber the complex number for which you want the base-2 logarithm 1359 * 1360 * @return string 1361 */ 1362 public static function IMLOG2($complexNumber) 1363 { 1364 $complexNumber = Functions::flattenSingleValue($complexNumber); 1365 1366 $complex = new Complex($complexNumber); 1367 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { 1368 return Functions::NAN(); 1369 } 1370 1371 return (string) (new Complex($complexNumber))->log2(); 1372 } 1373 1374 /** 1375 * IMEXP. 1376 * 1377 * Returns the exponential of a complex number in x + yi or x + yj text format. 1378 * 1379 * Excel Function: 1380 * IMEXP(complexNumber) 1381 * 1382 * @param string $complexNumber the complex number for which you want the exponential 1383 * 1384 * @return string 1385 */ 1386 public static function IMEXP($complexNumber) 1387 { 1388 $complexNumber = Functions::flattenSingleValue($complexNumber); 1389 1390 return (string) (new Complex($complexNumber))->exp(); 1391 } 1392 1393 /** 1394 * IMPOWER. 1395 * 1396 * Returns a complex number in x + yi or x + yj text format raised to a power. 1397 * 1398 * Excel Function: 1399 * IMPOWER(complexNumber,realNumber) 1400 * 1401 * @param string $complexNumber the complex number you want to raise to a power 1402 * @param float $realNumber the power to which you want to raise the complex number 1403 * 1404 * @return string 1405 */ 1406 public static function IMPOWER($complexNumber, $realNumber) 1407 { 1408 $complexNumber = Functions::flattenSingleValue($complexNumber); 1409 $realNumber = Functions::flattenSingleValue($realNumber); 1410 1411 if (!is_numeric($realNumber)) { 1412 return Functions::VALUE(); 1413 } 1414 1415 return (string) (new Complex($complexNumber))->pow($realNumber); 1416 } 1417 1418 /** 1419 * IMDIV. 1420 * 1421 * Returns the quotient of two complex numbers in x + yi or x + yj text format. 1422 * 1423 * Excel Function: 1424 * IMDIV(complexDividend,complexDivisor) 1425 * 1426 * @param string $complexDividend the complex numerator or dividend 1427 * @param string $complexDivisor the complex denominator or divisor 1428 * 1429 * @return string 1430 */ 1431 public static function IMDIV($complexDividend, $complexDivisor) 1432 { 1433 $complexDividend = Functions::flattenSingleValue($complexDividend); 1434 $complexDivisor = Functions::flattenSingleValue($complexDivisor); 1435 1436 try { 1437 return (string) (new Complex($complexDividend))->divideby(new Complex($complexDivisor)); 1438 } catch (ComplexException $e) { 1439 return Functions::NAN(); 1440 } 1441 } 1442 1443 /** 1444 * IMSUB. 1445 * 1446 * Returns the difference of two complex numbers in x + yi or x + yj text format. 1447 * 1448 * Excel Function: 1449 * IMSUB(complexNumber1,complexNumber2) 1450 * 1451 * @param string $complexNumber1 the complex number from which to subtract complexNumber2 1452 * @param string $complexNumber2 the complex number to subtract from complexNumber1 1453 * 1454 * @return string 1455 */ 1456 public static function IMSUB($complexNumber1, $complexNumber2) 1457 { 1458 $complexNumber1 = Functions::flattenSingleValue($complexNumber1); 1459 $complexNumber2 = Functions::flattenSingleValue($complexNumber2); 1460 1461 try { 1462 return (string) (new Complex($complexNumber1))->subtract(new Complex($complexNumber2)); 1463 } catch (ComplexException $e) { 1464 return Functions::NAN(); 1465 } 1466 } 1467 1468 /** 1469 * IMSUM. 1470 * 1471 * Returns the sum of two or more complex numbers in x + yi or x + yj text format. 1472 * 1473 * Excel Function: 1474 * IMSUM(complexNumber[,complexNumber[,...]]) 1475 * 1476 * @param string ...$complexNumbers Series of complex numbers to add 1477 * 1478 * @return string 1479 */ 1480 public static function IMSUM(...$complexNumbers) 1481 { 1482 // Return value 1483 $returnValue = new Complex(0.0); 1484 $aArgs = Functions::flattenArray($complexNumbers); 1485 1486 try { 1487 // Loop through the arguments 1488 foreach ($aArgs as $complex) { 1489 $returnValue = $returnValue->add(new Complex($complex)); 1490 } 1491 } catch (ComplexException $e) { 1492 return Functions::NAN(); 1493 } 1494 1495 return (string) $returnValue; 1496 } 1497 1498 /** 1499 * IMPRODUCT. 1500 * 1501 * Returns the product of two or more complex numbers in x + yi or x + yj text format. 1502 * 1503 * Excel Function: 1504 * IMPRODUCT(complexNumber[,complexNumber[,...]]) 1505 * 1506 * @param string ...$complexNumbers Series of complex numbers to multiply 1507 * 1508 * @return string 1509 */ 1510 public static function IMPRODUCT(...$complexNumbers) 1511 { 1512 // Return value 1513 $returnValue = new Complex(1.0); 1514 $aArgs = Functions::flattenArray($complexNumbers); 1515 1516 try { 1517 // Loop through the arguments 1518 foreach ($aArgs as $complex) { 1519 $returnValue = $returnValue->multiply(new Complex($complex)); 1520 } 1521 } catch (ComplexException $e) { 1522 return Functions::NAN(); 1523 } 1524 1525 return (string) $returnValue; 1526 } 1527 1528 /** 1529 * DELTA. 1530 * 1531 * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. 1532 * Use this function to filter a set of values. For example, by summing several DELTA 1533 * functions you calculate the count of equal pairs. This function is also known as the 1534 * Kronecker Delta function. 1535 * 1536 * Excel Function: 1537 * DELTA(a[,b]) 1538 * 1539 * @param float $a the first number 1540 * @param float $b The second number. If omitted, b is assumed to be zero. 1541 * 1542 * @return int 1543 */ 1544 public static function DELTA($a, $b = 0) 1545 { 1546 $a = Functions::flattenSingleValue($a); 1547 $b = Functions::flattenSingleValue($b); 1548 1549 return (int) ($a == $b); 1550 } 1551 1552 /** 1553 * GESTEP. 1554 * 1555 * Excel Function: 1556 * GESTEP(number[,step]) 1557 * 1558 * Returns 1 if number >= step; returns 0 (zero) otherwise 1559 * Use this function to filter a set of values. For example, by summing several GESTEP 1560 * functions you calculate the count of values that exceed a threshold. 1561 * 1562 * @param float $number the value to test against step 1563 * @param float $step The threshold value. 1564 * If you omit a value for step, GESTEP uses zero. 1565 * 1566 * @return int 1567 */ 1568 public static function GESTEP($number, $step = 0) 1569 { 1570 $number = Functions::flattenSingleValue($number); 1571 $step = Functions::flattenSingleValue($step); 1572 1573 return (int) ($number >= $step); 1574 } 1575 1576 // 1577 // Private method to calculate the erf value 1578 // 1579 private static $twoSqrtPi = 1.128379167095512574; 1580 1581 public static function erfVal($x) 1582 { 1583 if (abs($x) > 2.2) { 1584 return 1 - self::erfcVal($x); 1585 } 1586 $sum = $term = $x; 1587 $xsqr = ($x * $x); 1588 $j = 1; 1589 do { 1590 $term *= $xsqr / $j; 1591 $sum -= $term / (2 * $j + 1); 1592 ++$j; 1593 $term *= $xsqr / $j; 1594 $sum += $term / (2 * $j + 1); 1595 ++$j; 1596 if ($sum == 0.0) { 1597 break; 1598 } 1599 } while (abs($term / $sum) > Functions::PRECISION); 1600 1601 return self::$twoSqrtPi * $sum; 1602 } 1603 1604 /** 1605 * Validate arguments passed to the bitwise functions. 1606 * 1607 * @param mixed $value 1608 * 1609 * @return int 1610 */ 1611 private static function validateBitwiseArgument($value) 1612 { 1613 $value = Functions::flattenSingleValue($value); 1614 1615 if (is_int($value)) { 1616 return $value; 1617 } elseif (is_numeric($value)) { 1618 if ($value == (int) ($value)) { 1619 $value = (int) ($value); 1620 if (($value > 2 ** 48 - 1) || ($value < 0)) { 1621 throw new Exception(Functions::NAN()); 1622 } 1623 1624 return $value; 1625 } 1626 1627 throw new Exception(Functions::NAN()); 1628 } 1629 1630 throw new Exception(Functions::VALUE()); 1631 } 1632 1633 /** 1634 * BITAND. 1635 * 1636 * Returns the bitwise AND of two integer values. 1637 * 1638 * Excel Function: 1639 * BITAND(number1, number2) 1640 * 1641 * @param int $number1 1642 * @param int $number2 1643 * 1644 * @return int|string 1645 */ 1646 public static function BITAND($number1, $number2) 1647 { 1648 try { 1649 $number1 = self::validateBitwiseArgument($number1); 1650 $number2 = self::validateBitwiseArgument($number2); 1651 } catch (Exception $e) { 1652 return $e->getMessage(); 1653 } 1654 1655 return $number1 & $number2; 1656 } 1657 1658 /** 1659 * BITOR. 1660 * 1661 * Returns the bitwise OR of two integer values. 1662 * 1663 * Excel Function: 1664 * BITOR(number1, number2) 1665 * 1666 * @param int $number1 1667 * @param int $number2 1668 * 1669 * @return int|string 1670 */ 1671 public static function BITOR($number1, $number2) 1672 { 1673 try { 1674 $number1 = self::validateBitwiseArgument($number1); 1675 $number2 = self::validateBitwiseArgument($number2); 1676 } catch (Exception $e) { 1677 return $e->getMessage(); 1678 } 1679 1680 return $number1 | $number2; 1681 } 1682 1683 /** 1684 * BITXOR. 1685 * 1686 * Returns the bitwise XOR of two integer values. 1687 * 1688 * Excel Function: 1689 * BITXOR(number1, number2) 1690 * 1691 * @param int $number1 1692 * @param int $number2 1693 * 1694 * @return int|string 1695 */ 1696 public static function BITXOR($number1, $number2) 1697 { 1698 try { 1699 $number1 = self::validateBitwiseArgument($number1); 1700 $number2 = self::validateBitwiseArgument($number2); 1701 } catch (Exception $e) { 1702 return $e->getMessage(); 1703 } 1704 1705 return $number1 ^ $number2; 1706 } 1707 1708 /** 1709 * BITLSHIFT. 1710 * 1711 * Returns the number value shifted left by shift_amount bits. 1712 * 1713 * Excel Function: 1714 * BITLSHIFT(number, shift_amount) 1715 * 1716 * @param int $number 1717 * @param int $shiftAmount 1718 * 1719 * @return int|string 1720 */ 1721 public static function BITLSHIFT($number, $shiftAmount) 1722 { 1723 try { 1724 $number = self::validateBitwiseArgument($number); 1725 } catch (Exception $e) { 1726 return $e->getMessage(); 1727 } 1728 1729 $shiftAmount = Functions::flattenSingleValue($shiftAmount); 1730 1731 $result = $number << $shiftAmount; 1732 if ($result > 2 ** 48 - 1) { 1733 return Functions::NAN(); 1734 } 1735 1736 return $result; 1737 } 1738 1739 /** 1740 * BITRSHIFT. 1741 * 1742 * Returns the number value shifted right by shift_amount bits. 1743 * 1744 * Excel Function: 1745 * BITRSHIFT(number, shift_amount) 1746 * 1747 * @param int $number 1748 * @param int $shiftAmount 1749 * 1750 * @return int|string 1751 */ 1752 public static function BITRSHIFT($number, $shiftAmount) 1753 { 1754 try { 1755 $number = self::validateBitwiseArgument($number); 1756 } catch (Exception $e) { 1757 return $e->getMessage(); 1758 } 1759 1760 $shiftAmount = Functions::flattenSingleValue($shiftAmount); 1761 1762 return $number >> $shiftAmount; 1763 } 1764 1765 /** 1766 * ERF. 1767 * 1768 * Returns the error function integrated between the lower and upper bound arguments. 1769 * 1770 * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, 1771 * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was 1772 * improved, so that it can now calculate the function for both positive and negative ranges. 1773 * PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments. 1774 * 1775 * Excel Function: 1776 * ERF(lower[,upper]) 1777 * 1778 * @param float $lower lower bound for integrating ERF 1779 * @param float $upper upper bound for integrating ERF. 1780 * If omitted, ERF integrates between zero and lower_limit 1781 * 1782 * @return float|string 1783 */ 1784 public static function ERF($lower, $upper = null) 1785 { 1786 $lower = Functions::flattenSingleValue($lower); 1787 $upper = Functions::flattenSingleValue($upper); 1788 1789 if (is_numeric($lower)) { 1790 if ($upper === null) { 1791 return self::erfVal($lower); 1792 } 1793 if (is_numeric($upper)) { 1794 return self::erfVal($upper) - self::erfVal($lower); 1795 } 1796 } 1797 1798 return Functions::VALUE(); 1799 } 1800 1801 /** 1802 * ERFPRECISE. 1803 * 1804 * Returns the error function integrated between the lower and upper bound arguments. 1805 * 1806 * Excel Function: 1807 * ERF.PRECISE(limit) 1808 * 1809 * @param float $limit bound for integrating ERF 1810 * 1811 * @return float|string 1812 */ 1813 public static function ERFPRECISE($limit) 1814 { 1815 $limit = Functions::flattenSingleValue($limit); 1816 1817 return self::ERF($limit); 1818 } 1819 1820 // 1821 // Private method to calculate the erfc value 1822 // 1823 private static $oneSqrtPi = 0.564189583547756287; 1824 1825 private static function erfcVal($x) 1826 { 1827 if (abs($x) < 2.2) { 1828 return 1 - self::erfVal($x); 1829 } 1830 if ($x < 0) { 1831 return 2 - self::ERFC(-$x); 1832 } 1833 $a = $n = 1; 1834 $b = $c = $x; 1835 $d = ($x * $x) + 0.5; 1836 $q1 = $q2 = $b / $d; 1837 $t = 0; 1838 do { 1839 $t = $a * $n + $b * $x; 1840 $a = $b; 1841 $b = $t; 1842 $t = $c * $n + $d * $x; 1843 $c = $d; 1844 $d = $t; 1845 $n += 0.5; 1846 $q1 = $q2; 1847 $q2 = $b / $d; 1848 } while ((abs($q1 - $q2) / $q2) > Functions::PRECISION); 1849 1850 return self::$oneSqrtPi * exp(-$x * $x) * $q2; 1851 } 1852 1853 /** 1854 * ERFC. 1855 * 1856 * Returns the complementary ERF function integrated between x and infinity 1857 * 1858 * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, 1859 * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was 1860 * improved, so that it can now calculate the function for both positive and negative x values. 1861 * PhpSpreadsheet follows Excel 2010 behaviour, and accepts nagative arguments. 1862 * 1863 * Excel Function: 1864 * ERFC(x) 1865 * 1866 * @param float $x The lower bound for integrating ERFC 1867 * 1868 * @return float|string 1869 */ 1870 public static function ERFC($x) 1871 { 1872 $x = Functions::flattenSingleValue($x); 1873 1874 if (is_numeric($x)) { 1875 return self::erfcVal($x); 1876 } 1877 1878 return Functions::VALUE(); 1879 } 1880 1881 /** 1882 * getConversionGroups 1883 * Returns a list of the different conversion groups for UOM conversions. 1884 * 1885 * @Deprecated Use the getConversionCategories() method in the ConvertUOM class instead 1886 * 1887 * @return array 1888 */ 1889 public static function getConversionGroups() 1890 { 1891 return Engineering\ConvertUOM::getConversionCategories(); 1892 } 1893 1894 /** 1895 * getConversionGroupUnits 1896 * Returns an array of units of measure, for a specified conversion group, or for all groups. 1897 * 1898 * @Deprecated Use the getConversionCategoryUnits() method in the ConvertUOM class instead 1899 * 1900 * @param null|mixed $category 1901 * 1902 * @return array 1903 */ 1904 public static function getConversionGroupUnits($category = null) 1905 { 1906 return Engineering\ConvertUOM::getConversionCategoryUnits($category); 1907 } 1908 1909 /** 1910 * getConversionGroupUnitDetails. 1911 * 1912 * @Deprecated Use the getConversionCategoryUnitDetails() method in the ConvertUOM class instead 1913 * 1914 * @param null|mixed $category 1915 * 1916 * @return array 1917 */ 1918 public static function getConversionGroupUnitDetails($category = null) 1919 { 1920 return Engineering\ConvertUOM::getConversionCategoryUnitDetails($category); 1921 } 1922 1923 /** 1924 * getConversionMultipliers 1925 * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). 1926 * 1927 * @Deprecated Use the getConversionMultipliers() method in the ConvertUOM class instead 1928 * 1929 * @return array of mixed 1930 */ 1931 public static function getConversionMultipliers() 1932 { 1933 return Engineering\ConvertUOM::getConversionMultipliers(); 1934 } 1935 1936 /** 1937 * getBinaryConversionMultipliers 1938 * Returns an array of the additional Multiplier prefixes that can be used with Information Units of Measure in CONVERTUOM(). 1939 * 1940 * @Deprecated Use the getBinaryConversionMultipliers() method in the ConvertUOM class instead 1941 * 1942 * @return array of mixed 1943 */ 1944 public static function getBinaryConversionMultipliers() 1945 { 1946 return Engineering\ConvertUOM::getBinaryConversionMultipliers(); 1947 } 1948 1949 /** 1950 * CONVERTUOM. 1951 * 1952 * Converts a number from one measurement system to another. 1953 * For example, CONVERT can translate a table of distances in miles to a table of distances 1954 * in kilometers. 1955 * 1956 * Excel Function: 1957 * CONVERT(value,fromUOM,toUOM) 1958 * 1959 * @Deprecated Use the CONVERT() method in the ConvertUOM class instead 1960 * 1961 * @param float|int $value the value in fromUOM to convert 1962 * @param string $fromUOM the units for value 1963 * @param string $toUOM the units for the result 1964 * 1965 * @return float|string 1966 */ 1967 public static function CONVERTUOM($value, $fromUOM, $toUOM) 1968 { 1969 return Engineering\ConvertUOM::CONVERT($value, $fromUOM, $toUOM); 1970 } 1971 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body