New Bessel Algorithm, providing a higher degree of accuracy and precision (#1946)

* New Bessel Algorithm, providing a higher degree of precision (12 decimal places) and still matching/exceeding MS Excel's precision across the range of values
This commit is contained in:
Mark Baker 2021-03-24 13:29:54 +01:00 committed by GitHub
parent 1a7b9a446a
commit 07ad800755
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1078 additions and 641 deletions

View File

@ -3,7 +3,6 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
class BesselI
{
@ -16,9 +15,12 @@ class BesselI
* Excel Function:
* BESSELI(x,ord)
*
* @param float $x The value at which to evaluate the function.
* NOTE: The MS Excel implementation of the BESSELI function is still not accurate.
* This code provides a more accurate calculation
*
* @param mixed (float) $x The value at which to evaluate the function.
* If x is nonnumeric, BESSELI returns the #VALUE! error value.
* @param int $ord The order of the Bessel function.
* @param mixed (int) $ord The order of the Bessel function.
* If ord is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELI returns the #VALUE! error value.
* If $ord < 0, BESSELI returns the #NUM! error value.
@ -28,7 +30,7 @@ class BesselI
public static function BESSELI($x, $ord)
{
$x = ($x === null) ? 0.0 : Functions::flattenSingleValue($x);
$ord = ($ord === null) ? 0.0 : Functions::flattenSingleValue($ord);
$ord = ($ord === null) ? 0 : Functions::flattenSingleValue($ord);
if ((is_numeric($x)) && (is_numeric($ord))) {
$ord = (int) floor($ord);
@ -36,7 +38,7 @@ class BesselI
return Functions::NAN();
}
$fResult = self::calculate($x, $ord);
$fResult = self::calculate((float) $x, $ord);
return (is_nan($fResult)) ? Functions::NAN() : $fResult;
}
@ -46,27 +48,87 @@ class BesselI
private static function calculate(float $x, int $ord): float
{
if (abs($x) <= 30) {
$fResult = $fTerm = ($x / 2) ** $ord / MathTrig::FACT($ord);
$ordK = 1;
$fSqrX = ($x * $x) / 4;
do {
$fTerm *= $fSqrX;
$fTerm /= ($ordK * ($ordK + $ord));
$fResult += $fTerm;
} while ((abs($fTerm) > 1e-12) && (++$ordK < 100));
return $fResult;
// special cases
switch ($ord) {
case 0:
return self::besselI0($x);
case 1:
return self::besselI1($x);
}
$f_2_PI = 2 * M_PI;
$fXAbs = abs($x);
$fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs);
if (($ord & 1) && ($x < 0)) {
$fResult = -$fResult;
return self::besselI2($x, $ord);
}
return $fResult;
private static function besselI0(float $x): float
{
$ax = abs($x);
if ($ax < 3.75) {
$y = $x / 3.75;
$y = $y * $y;
return 1.0 + $y * (3.5156229 + $y * (3.0899424 + $y * (1.2067492
+ $y * (0.2659732 + $y * (0.360768e-1 + $y * 0.45813e-2)))));
}
$y = 3.75 / $ax;
return (exp($ax) / sqrt($ax)) * (0.39894228 + $y * (0.1328592e-1 + $y * (0.225319e-2 + $y * (-0.157565e-2
+ $y * (0.916281e-2 + $y * (-0.2057706e-1 + $y * (0.2635537e-1 +
$y * (-0.1647633e-1 + $y * 0.392377e-2))))))));
}
private static function besselI1(float $x): float
{
$ax = abs($x);
if ($ax < 3.75) {
$y = $x / 3.75;
$y = $y * $y;
$ans = $ax * (0.5 + $y * (0.87890594 + $y * (0.51498869 + $y * (0.15084934 + $y * (0.2658733e-1 +
$y * (0.301532e-2 + $y * 0.32411e-3))))));
return ($x < 0.0) ? -$ans : $ans;
}
$y = 3.75 / $ax;
$ans = 0.2282967e-1 + $y * (-0.2895312e-1 + $y * (0.1787654e-1 - $y * 0.420059e-2));
$ans = 0.39894228 + $y * (-0.3988024e-1 + $y * (-0.362018e-2 + $y * (0.163801e-2 +
$y * (-0.1031555e-1 + $y * $ans))));
$ans *= exp($ax) / sqrt($ax);
return ($x < 0.0) ? -$ans : $ans;
}
private static function besselI2(float $x, int $ord): float
{
if ($x === 0.0) {
return 0.0;
}
$tox = 2.0 / abs($x);
$bip = 0;
$ans = 0.0;
$bi = 1.0;
for ($j = 2 * ($ord + (int) sqrt(40.0 * $ord)); $j > 0; --$j) {
$bim = $bip + $j * $tox * $bi;
$bip = $bi;
$bi = $bim;
if (abs($bi) > 1.0e+12) {
$ans *= 1.0e-12;
$bi *= 1.0e-12;
$bip *= 1.0e-12;
}
if ($j === $ord) {
$ans = $bip;
}
}
$ans *= self::besselI0($x) / $bi;
return ($x < 0.0 && (($ord % 2) === 1)) ? -$ans : $ans;
}
}

View File

@ -3,7 +3,6 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
class BesselJ
{
@ -15,9 +14,12 @@ class BesselJ
* Excel Function:
* BESSELJ(x,ord)
*
* @param float $x The value at which to evaluate the function.
* NOTE: The MS Excel implementation of the BESSELJ function is still not accurate, particularly for higher order
* values with x < -8 and x > 8. This code provides a more accurate calculation
*
* @param mixed (float) $x The value at which to evaluate the function.
* If x is nonnumeric, BESSELJ returns the #VALUE! error value.
* @param int $ord The order of the Bessel function. If n is not an integer, it is truncated.
* @param mixed (int) $ord The order of the Bessel function. If n is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELJ returns the #VALUE! error value.
* If $ord < 0, BESSELJ returns the #NUM! error value.
*
@ -34,7 +36,7 @@ class BesselJ
return Functions::NAN();
}
$fResult = self::calculate($x, $ord);
$fResult = self::calculate((float) $x, $ord);
return (is_nan($fResult)) ? Functions::NAN() : $fResult;
}
@ -44,28 +46,123 @@ class BesselJ
private static function calculate(float $x, int $ord): float
{
if (abs($x) <= 30) {
$fResult = $fTerm = ($x / 2) ** $ord / MathTrig::FACT($ord);
$ordK = 1;
$fSqrX = ($x * $x) / -4;
do {
$fTerm *= $fSqrX;
$fTerm /= ($ordK * ($ordK + $ord));
$fResult += $fTerm;
} while ((abs($fTerm) > 1e-12) && (++$ordK < 100));
return $fResult;
// special cases
switch ($ord) {
case 0:
return self::besselJ0($x);
case 1:
return self::besselJ1($x);
}
$f_PI_DIV_2 = M_PI / 2;
$f_PI_DIV_4 = M_PI / 4;
$fXAbs = abs($x);
$fResult = sqrt(Functions::M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4);
if (($ord & 1) && ($x < 0)) {
$fResult = -$fResult;
return self::besselJ2($x, $ord);
}
return $fResult;
private static function besselJ0(float $x): float
{
$ax = abs($x);
if ($ax < 8.0) {
$y = $x * $x;
$ans1 = 57568490574.0 + $y * (-13362590354.0 + $y * (651619640.7 + $y * (-11214424.18 + $y *
(77392.33017 + $y * (-184.9052456)))));
$ans2 = 57568490411.0 + $y * (1029532985.0 + $y * (9494680.718 + $y * (59272.64853 + $y *
(267.8532712 + $y * 1.0))));
return $ans1 / $ans2;
}
$z = 8.0 / $ax;
$y = $z * $z;
$xx = $ax - 0.785398164;
$ans1 = 1.0 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6)));
$ans2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y *
(0.7621095161e-6 - $y * 0.934935152e-7)));
return sqrt(0.636619772 / $ax) * (cos($xx) * $ans1 - $z * sin($xx) * $ans2);
}
private static function besselJ1(float $x): float
{
$ax = abs($x);
if ($ax < 8.0) {
$y = $x * $x;
$ans1 = $x * (72362614232.0 + $y * (-7895059235.0 + $y * (242396853.1 + $y *
(-2972611.439 + $y * (15704.48260 + $y * (-30.16036606))))));
$ans2 = 144725228442.0 + $y * (2300535178.0 + $y * (18583304.74 + $y * (99447.43394 + $y *
(376.9991397 + $y * 1.0))));
return $ans1 / $ans2;
}
$z = 8.0 / $ax;
$y = $z * $z;
$xx = $ax - 2.356194491;
$ans1 = 1.0 + $y * (0.183105e-2 + $y * (-0.3516396496e-4 + $y * (0.2457520174e-5 + $y * (-0.240337019e-6))));
$ans2 = 0.04687499995 + $y * (-0.2002690873e-3 + $y * (0.8449199096e-5 + $y *
(-0.88228987e-6 + $y * 0.105787412e-6)));
$ans = sqrt(0.636619772 / $ax) * (cos($xx) * $ans1 - $z * sin($xx) * $ans2);
return ($x < 0.0) ? -$ans : $ans;
}
private static function besselJ2(float $x, int $ord): float
{
$ax = abs($x);
if ($ax === 0.0) {
return 0.0;
}
if ($ax > $ord) {
return self::besselj2a($ax, $ord, $x);
}
return self::besselj2b($ax, $ord, $x);
}
private static function besselj2a(float $ax, int $ord, float $x)
{
$tox = 2.0 / $ax;
$bjm = self::besselJ0($ax);
$bj = self::besselJ1($ax);
for ($j = 1; $j < $ord; ++$j) {
$bjp = $j * $tox * $bj - $bjm;
$bjm = $bj;
$bj = $bjp;
}
$ans = $bj;
return ($x < 0.0 && ($ord % 2) == 1) ? -$ans : $ans;
}
private static function besselj2b(float $ax, int $ord, float $x)
{
$tox = 2.0 / $ax;
$jsum = false;
$bjp = $ans = $sum = 0.0;
$bj = 1.0;
for ($j = 2 * ($ord + (int) sqrt(40.0 * $ord)); $j > 0; --$j) {
$bjm = $j * $tox * $bj - $bjp;
$bjp = $bj;
$bj = $bjm;
if (abs($bj) > 1.0e+10) {
$bj *= 1.0e-10;
$bjp *= 1.0e-10;
$ans *= 1.0e-10;
$sum *= 1.0e-10;
}
if ($jsum === true) {
$sum += $bj;
}
$jsum = !$jsum;
if ($j === $ord) {
$ans = $bjp;
}
}
$sum = 2.0 * $sum - $bj;
$ans /= $sum;
return ($x < 0.0 && ($ord % 2) === 1) ? -$ans : $ans;
}
}

View File

@ -15,9 +15,9 @@ class BesselK
* Excel Function:
* BESSELK(x,ord)
*
* @param float $x The value at which to evaluate the function.
* @param mixed (float) $x The value at which to evaluate the function.
* If x is nonnumeric, BESSELK returns the #VALUE! error value.
* @param int $ord The order of the Bessel function. If n is not an integer, it is truncated.
* @param mixed (int) $ord The order of the Bessel function. If n is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELK returns the #VALUE! error value.
* If $ord < 0, BESSELK returns the #NUM! error value.
*
@ -29,22 +29,13 @@ class BesselK
$ord = ($ord === null) ? 0 : Functions::flattenSingleValue($ord);
if ((is_numeric($x)) && (is_numeric($ord))) {
if (($ord < 0) || ($x == 0.0)) {
$ord = (int) floor($ord);
$x = (float) $x;
if (($ord < 0) || ($x <= 0.0)) {
return Functions::NAN();
}
switch (floor($ord)) {
case 0:
$fBk = self::besselK0($x);
break;
case 1:
$fBk = self::besselK1($x);
break;
default:
$fBk = self::besselK2($x, $ord);
}
$fBk = self::calculate($x, $ord);
return (is_nan($fBk)) ? Functions::NAN() : $fBk;
}
@ -52,38 +43,51 @@ class BesselK
return Functions::VALUE();
}
private static function besselK0(float $fNum): float
private static function calculate($x, $ord): float
{
if ($fNum <= 2) {
$fNum2 = $fNum * 0.5;
// special cases
switch (floor($ord)) {
case 0:
return self::besselK0($x);
case 1:
return self::besselK1($x);
}
return self::besselK2($x, $ord);
}
private static function besselK0(float $x): float
{
if ($x <= 2) {
$fNum2 = $x * 0.5;
$y = ($fNum2 * $fNum2);
return -log($fNum2) * BesselI::BESSELI($fNum, 0) +
return -log($fNum2) * BesselI::BESSELI($x, 0) +
(-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y *
(0.10750e-3 + $y * 0.74e-5))))));
}
$y = 2 / $fNum;
$y = 2 / $x;
return exp(-$fNum) / sqrt($fNum) *
return exp(-$x) / sqrt($x) *
(1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y *
(0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3))))));
}
private static function besselK1(float $fNum): float
private static function besselK1(float $x): float
{
if ($fNum <= 2) {
$fNum2 = $fNum * 0.5;
if ($x <= 2) {
$fNum2 = $x * 0.5;
$y = ($fNum2 * $fNum2);
return log($fNum2) * BesselI::BESSELI($fNum, 1) +
return log($fNum2) * BesselI::BESSELI($x, 1) +
(1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y *
(-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum;
(-0.110404e-2 + $y * (-0.4686e-4))))))) / $x;
}
$y = 2 / $fNum;
$y = 2 / $x;
return exp(-$fNum) / sqrt($fNum) *
return exp(-$x) / sqrt($x) *
(1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y *
(0.325614e-2 + $y * (-0.68245e-3)))))));
}

View File

@ -14,9 +14,9 @@ class BesselY
* Excel Function:
* BESSELY(x,ord)
*
* @param float $x The value at which to evaluate the function.
* @param mixed (float) $x The value at which to evaluate the function.
* If x is nonnumeric, BESSELY returns the #VALUE! error value.
* @param int $ord The order of the Bessel function. If n is not an integer, it is truncated.
* @param mixed (int) $ord The order of the Bessel function. If n is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELY returns the #VALUE! error value.
* If $ord < 0, BESSELY returns the #NUM! error value.
*
@ -28,22 +28,13 @@ class BesselY
$ord = ($ord === null) ? 0 : Functions::flattenSingleValue($ord);
if ((is_numeric($x)) && (is_numeric($ord))) {
if (($ord < 0) || ($x == 0.0)) {
$ord = (int) floor($ord);
$x = (float) $x;
if (($ord < 0) || ($x <= 0.0)) {
return Functions::NAN();
}
switch (floor($ord)) {
case 0:
$fBy = self::besselY0($x);
break;
case 1:
$fBy = self::besselY1($x);
break;
default:
$fBy = self::besselY2($x, $ord);
}
$fBy = self::calculate($x, $ord);
return (is_nan($fBy)) ? Functions::NAN() : $fBy;
}
@ -51,46 +42,66 @@ class BesselY
return Functions::VALUE();
}
private static function besselY0(float $fNum): float
private static function calculate($x, $ord): float
{
if ($fNum < 8.0) {
$y = ($fNum * $fNum);
$f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y *
// special cases
switch (floor($ord)) {
case 0:
return self::besselY0($x);
case 1:
return self::besselY1($x);
}
return self::besselY2($x, $ord);
}
private static function besselY0(float $x): float
{
if ($x < 8.0) {
$y = ($x * $x);
$ans1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y *
(-86327.92757 + $y * 228.4622733))));
$f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y *
$ans2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y *
(47447.26470 + $y * (226.1030244 + $y))));
return $f1 / $f2 + 0.636619772 * BesselJ::BESSELJ($fNum, 0) * log($fNum);
return $ans1 / $ans2 + 0.636619772 * BesselJ::BESSELJ($x, 0) * log($x);
}
$z = 8.0 / $fNum;
$z = 8.0 / $x;
$y = ($z * $z);
$xx = $fNum - 0.785398164;
$f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6)));
$f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y *
$xx = $x - 0.785398164;
$ans1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6)));
$ans2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y *
(-0.934945152e-7))));
return sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2);
return sqrt(0.636619772 / $x) * (sin($xx) * $ans1 + $z * cos($xx) * $ans2);
}
private static function besselY1(float $fNum): float
private static function besselY1(float $x): float
{
if ($fNum < 8.0) {
$y = ($fNum * $fNum);
$f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y *
if ($x < 8.0) {
$y = ($x * $x);
$ans1 = $x * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y *
(0.7349264551e9 + $y * (-0.4237922726e7 + $y * 0.8511937935e4)))));
$f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y *
$ans2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y *
(0.1020426050e6 + $y * (0.3549632885e3 + $y)))));
return $f1 / $f2 + 0.636619772 * (BesselJ::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum);
return ($ans1 / $ans2) + 0.636619772 * (BesselJ::BESSELJ($x, 1) * log($x) - 1 / $x);
}
return sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491);
$z = 8.0 / $x;
$y = $z * $z;
$xx = $x - 2.356194491;
$ans1 = 1.0 + $y * (0.183105e-2 + $y * (-0.3516396496e-4 + $y * (0.2457520174e-5 + $y * (-0.240337019e-6))));
$ans2 = 0.04687499995 + $y * (-0.2002690873e-3 + $y * (0.8449199096e-5 + $y *
(-0.88228987e-6 + $y * 0.105787412e-6)));
return sqrt(0.636619772 / $x) * (sin($xx) * $ans1 + $z * cos($xx) * $ans2);
}
private static function besselY2(float $x, int $ord)
private static function besselY2(float $x, int $ord): float
{
$fTox = 2 / $x;
$fTox = 2.0 / $x;
$fBym = self::besselY0($x);
$fBy = self::besselY1($x);
for ($n = 1; $n < $ord; ++$n) {

View File

@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselITest extends TestCase
{
const BESSEL_PRECISION = 1E-8;
const BESSEL_PRECISION = 1E-9;
protected function setUp(): void
{

View File

@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselKTest extends TestCase
{
const BESSEL_PRECISION = 1E-8;
const BESSEL_PRECISION = 1E-12;
protected function setUp(): void
{

View File

@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselYTest extends TestCase
{
const BESSEL_PRECISION = 1E-8;
const BESSEL_PRECISION = 1E-12;
protected function setUp(): void
{

View File

@ -1,10 +1,10 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\TextData\Concatenate;
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
@ -19,7 +19,7 @@ class ReptTest extends TestCase
*/
public function testReptDirect($expectedResult, $val = null, $rpt = null): void
{
$result = Concatenate::builtinREPT(is_string($val) ? trim($val, '"') : $val, $rpt);
$result = TextData::builtinREPT(is_string($val) ? trim($val, '"') : $val, $rpt);
self::assertEquals($expectedResult, $result);
}

View File

@ -6,208 +6,12 @@ return [
1.5, -1,
],
[
2.249E-5,
-1, 6,
],
[
0.0,
0, 3,
],
[
4.8807925900000004,
3, 0,
],
[
0.00027146000000000001,
1, 5,
],
[
0.98166642999999998,
1.5, 1,
],
[
0.33783461999999997,
-1.5, 2.5,
],
[
0.0,
-1.5, 14.99,
],
[
0.0,
1, 30,
],
[
2.51671625,
2.5, 1,
],
[
2.51671625,
2.5, 1.5,
],
[
-2.51671625,
-2.5, 1.5,
],
[
6.20583492,
3.5, 1,
],
[
0.0073673699999999998,
0.69999999999999996, 3,
],
[
3.8320120499999999,
3.5, 2,
'#VALUE!',
'NaN', 1,
],
[
'#VALUE!',
1.5, 'XYZ',
],
[
'#VALUE!',
'ABC', 3,
],
[
-1030.9147225199999,
-9, 1,
],
[
-6.20583492,
-3.5, 1,
],
[
-0.39288151999999998,
-0.73499999999999999, 1,
],
[
0.0,
0, 1,
],
[
0.01750268,
0.035000000000000003, 1,
],
[
0.56515910000000003,
1, 1,
],
[
0.98166642999999998,
1.5, 1,
],
[
2.51671625,
2.5, 1,
],
[
6.20583492,
3.5, 1,
],
[
864.49619395000002,
-9, 2,
],
[
3.8320120499999999,
-3.5, 2,
],
[
0.070619940000000006,
-0.73499999999999999, 2,
],
[
0.0,
0, 2,
],
[
0.00015313999999999999,
0.035000000000000003, 2,
],
[
0.10825973,
0.90000000000000002, 2,
],
[
0.13574766999999999,
1, 2,
],
[
0.60327242999999997,
1.8999999999999999, 2,
],
[
1.2764661500000001,
2.5, 2,
],
[
3.8320120499999999,
3.5, 2,
],
[
6.4221893799999998,
4, 2,
],
[
8.8999999999999995E-7,
0.035000000000000003, 3,
],
[
0.0073673699999999998,
0.69999999999999996, 3,
],
[
0.0154285,
0.89000000000000001, 3,
],
[
3.3372757800000001,
4, 3,
],
[
0.50472435999999998,
4, 5,
],
[
2.8410000000000001E-5,
1.5, 7,
],
[
0.00013237000000000001,
3, 9,
],
[
7.3782034300000001,
-3.5, 0,
],
[
1.6467231899999999,
-1.5, 0,
],
[
1.0,
0, 0,
],
[
1.26606588,
1, 0,
],
[
1.6467231899999999,
1.5, 0,
],
[
3.2898391400000002,
2.5, 0,
],
[
7.3782034300000001,
3.5, 0,
],
[
'#NUM!',
-3.5, -1,
1.5, 'NaN',
],
[
'#VALUE!',
@ -215,10 +19,290 @@ return [
],
[
'#VALUE!',
1, true,
1.5, true,
],
[
104777847.71856035,
21, 2,
30596.33413506702,
-12.5, 0,
],
[
2815.7166648041534,
-10, 0,
],
[
268.161313800963,
-7.5, 0,
],
[
7.37820347757186,
-3.5, 0,
],
[
3.28983917239129,
-2.5, 0,
],
[
1.26606584803426,
-1, 0,
],
[
1.00391006406612,
-0.125, 0,
],
[
1.0,
0, 0,
],
[
1.00391006406612,
0.125, 0,
],
[
1.26606584803426,
1, 0,
],
[
3.28983917239129,
2.5, 0,
],
[
7.37820347757186,
3.5, 0,
],
[
427.564125313702,
8, 0,
],
[
30596.33413506702,
12.5, 0,
],
[
306693019.30610687,
22, 0,
],
[
5590908218797.506,
32, 0,
],
[
-29345.751017210714,
-12.5, 1,
],
[
-2670.988320559247,
-10, 1,
],
[
-249.584367947395,
-7.5, 1,
],
[
-6.205834932063,
-3.5, 1,
],
[
-2.51671624202536,
-2.5, 1,
],
[
-0.565159097581943,
-1, 1,
],
[
-0.062622149768879,
-0.125, 1,
],
[
0.0,
0, 1,
],
[
0.062622149768879,
0.125, 1,
],
[
0.565159097581943,
1, 1,
],
[
2.51671624202536,
2.5, 1,
],
[
6.205834932063,
3.5, 1,
],
[
399.873134789592,
8, 1,
],
[
29345.751017210714,
12.5, 1,
],
[
299639573.1780888,
22, 1,
],
[
5502845662755.76,
32, 1,
],
[
25901.0143489759,
-12.5, 2,
],
[
2281.518997169878,
-10, 2,
],
[
201.605482454266,
-7.5, 2,
],
[
3.83201207162936,
-3.5, 2,
],
[
1.27646615881561,
-2.5, 2,
],
[
0.135747666580699,
-1, 2,
],
[
0.001955669369142,
-0.125, 2,
],
[
0.0,
0, 2,
],
[
0.001955669369142,
0.125, 2,
],
[
0.135747666580699,
1, 2,
],
[
1.27646615881561,
2.5, 2,
],
[
3.83201207162936,
3.5, 2,
],
[
327.595838875391,
8, 2,
],
[
25901.0143489759,
12.5, 2,
],
[
279453053.1335468,
22, 2,
],
[
5246981502816.42,
32, 2,
],
[
-10949.6155627918,
-12.5, 5,
],
[
-777.188296433171,
-10, 5,
],
[
-48.2413608068669,
-7.5, 5,
],
[
-0.223984956078518,
-3.5, 5,
],
[
-0.032843475454962,
-2.5, 5,
],
[
-0.000271463149585,
-1, 5,
],
[
-0.000000007952461,
-0.125, 5,
],
[
0.0,
0, 5,
],
[
0.000000007952461,
0.125, 5,
],
[
0.000271463149585,
1, 5,
],
[
0.032843475454962,
2.5, 5,
],
[
0.223984956078518,
3.5, 5,
],
[
85.5358071768162,
8, 5,
],
[
10949.6155627918,
12.5, 5,
],
[
171888048.06410483,
22, 5,
],
[
3762429557237.2134,
32, 5,
],
[
-0.002645111902465,
-0.5, 3.5,
],
[
-0.257894303289036,
-0.5, 1.5,
],
[
1.06348334399461,
-0.5, 0.5,
],
[
1.06348334399461,
0.5, 0.5,
],
[
0.25789430328903,
0.5, 1.5,
],
[
0.002645111902465,
0.5, 3.5,
],
[
188340493120020360000000000.0,
64, 8,
],
];

View File

@ -3,167 +3,307 @@
return [
[
'#NUM!',
1.5,
-1,
],
[
0.0,
0,
1,
],
[
0.44005059000000002,
1,
1,
],
[
0.00024976000000000002,
1,
5,
],
[
0.32992572999999997,
1.8999999999999999,
2,
],
[
-0.49709409999999998,
-2.5,
1.5,
],
[
0.13737753,
3.5,
1,
],
[
0.013974,
0.89000000000000001,
3,
],
[
0.45862918000000003,
3.5,
2,
1.5, -1,
],
[
'#VALUE!',
1.5,
'XYZ',
'NaN', 1,
],
[
'#VALUE!',
'ABC',
3,
1.5, 'NaN',
],
[
-0.13737753,
-3.5,
1,
'#VALUE!',
true, 1,
],
[
-0.34323577999999999,
-0.73499999999999999,
1,
'#VALUE!',
1.5, true,
],
[
0.146884054700421,
-12.5, 0,
],
[
-0.245935764451348,
-10, 0,
],
[
0.266339657880379,
-7.5, 0,
],
[
-0.380127739987264,
-3.5, 0,
],
[
-0.048383776468198,
-2.5, 0,
],
[
0.765197686557967,
-1, 0,
],
[
0.996097563041985,
-0.125, 0,
],
[
1.0,
0, 0,
],
[
0.996097563041985,
0.125, 0,
],
[
0.765197686557967,
1, 0,
],
[
-0.048383776468198,
2.5, 0,
],
[
-0.380127739987264,
3.5, 0,
],
[
0.171650807137554,
8, 0,
],
[
0.146884054700421,
12.5, 0,
],
[
-0.120651475704867,
22, 0,
],
[
0.138079009746556,
32, 0,
],
[
0.165483804614760,
-12.5, 1,
],
[
-0.043472746168862,
-10, 1,
],
[
-0.135248427579706,
-7.5, 1,
],
[
-0.137377527362327,
-3.5, 1,
],
[
-0.497094102464274,
-2.5, 1,
],
[
-0.440050585744933,
-1, 1,
],
[
-0.062378009134495,
-0.125, 1,
],
[
0.0,
0,
1,
0, 1,
],
[
0.01749732,
0.035000000000000003,
1,
0.062378009134495,
0.125, 1,
],
[
0.55793651,
1.5,
1,
0.440050585744933,
1, 1,
],
[
0.49709409999999998,
2.5,
1,
0.497094102464274,
2.5, 1,
],
[
0.13737753,
3.5,
1,
0.137377527362327,
3.5, 1,
],
[
0.14484733999999999,
-9,
2,
0.234636346853915,
8, 1,
],
[
0.064538960000000006,
-0.73499999999999999,
2,
-0.165483804614760,
12.5, 1,
],
[
0.117177789643852,
22, 1,
],
[
-0.026589028475905,
32, 1,
],
[
-0.173361463438783,
-12.5, 2,
],
[
0.254630313685121,
-10, 2,
],
[
-0.230273410525790,
-7.5, 2,
],
[
0.458629184194308,
-3.5, 2,
],
[
0.446059058439617,
-2.5, 2,
],
[
0.114903484931900,
-1, 2,
],
[
0.001950583109930,
-0.125, 2,
],
[
0.0,
0,
2,
0, 2,
],
[
0.094586299999999998,
0.90000000000000002,
2,
0.001950583109930,
0.125, 2,
],
[
0.32992572999999997,
1.8999999999999999,
2,
0.114903484931900,
1, 2,
],
[
0.00015311,
0.035000000000000003,
2,
0.446059058439617,
2.5, 2,
],
[
0.45862918000000003,
3.5,
2,
0.458629184194308,
3.5, 2,
],
[
0.36412814999999998,
4,
2,
-0.112991720424075,
8, 2,
],
[
8.8999999999999995E-7,
0.035000000000000003,
3,
-0.173361463438783,
12.5, 2,
],
[
0.0069296499999999999,
0.69999999999999996,
3,
0.131304002036127,
22, 2,
],
[
0.013974,
0.89000000000000001,
3,
-0.139740824026300,
32, 2,
],
[
0.43017147,
4,
3,
-0.034737699762240,
-12.5, 5,
],
[
0.13208665999999999,
4,
5,
0.234061528186794,
-10, 5,
],
[
2.4680000000000001E-5,
1.5,
7,
-0.283473905162551,
-7.5, 5,
],
[
8.4400000000000005E-5,
3,
9,
-0.080441986647992,
-3.5, 5,
],
[
-0.019501625134503,
-2.5, 5,
],
[
-0.000249757730211,
-1, 5,
],
[
-0.000000007942113,
-0.125, 5,
],
[
0.0,
0, 5,
],
[
0.000000007942113,
0.125, 5,
],
[
0.000249757730211,
1, 5,
],
[
0.019501625134503,
2.5, 5,
],
[
0.080441986647992,
3.5, 5,
],
[
0.185774772190564,
8, 5,
],
[
0.034737699762240,
12.5, 5,
],
[
0.036304102444491,
22, 5,
],
[
0.026241347352986,
32, 5,
],
[
-0.002563729994587,
-0.5, 3.5,
],
[
-0.242268457674874,
-0.5, 1.5,
],
[
0.938469807240813,
-0.5, 0.5,
],
[
0.938469807240813,
0.5, 0.5,
],
[
0.242268457674874,
0.5, 1.5,
],
[
0.002563729994587,
0.5, 3.5,
],
[
0.063689476134356,
64, 8,
],
];

View File

@ -3,192 +3,174 @@
return [
[
'#NUM!',
1.5,
-1,
],
[
'#NUM!',
0,
2,
],
[
7990.0124327800004,
0.10000000000000001,
3,
],
[
0.42102444,
1,
0,
],
[
0.21380557,
1.5,
0,
],
[
'#NUM!',
-1.5,
2,
],
[
0.27738780000000002,
1.5,
1,
],
[
0.58365597000000002,
1.5,
2,
],
[
0.094982449999999996,
2.2999999999999998,
1.5,
],
[
0.073890819999999996,
2.5,
1,
],
[
0.022239390000000001,
3.5,
1,
],
[
0.059161819999999997,
3.5,
3,
],
[
397.95880105999998,
3,
9,
],
[
0.032307120000000002,
3.5,
2,
1.5, -1,
],
[
'#VALUE!',
1.5,
'XYZ',
'NaN', 1,
],
[
'#VALUE!',
'ABC',
3,
1.5, 'NaN',
],
[
'#NUM!',
-3.5,
1,
-1.5, 1,
],
[
'#NUM!',
-0.73499999999999999,
1,
0.0, 1,
],
[
'#NUM!',
0,
1,
'#VALUE!',
true, 1,
],
[
28.50197,
0.035000000000000003,
1,
'#VALUE!',
1.5, true,
],
[
0.27738780000000002,
1.5,
1,
2.20786908479938,
0.125, 0,
],
[
0.073890819999999996,
2.5,
1,
0.421024421083418,
1, 0,
],
[
0.022239390000000001,
3.5,
1,
0.062347554191019,
2.5, 0,
],
[
'#NUM!',
-9,
2,
0.019598896971074,
3.5, 0,
],
[
'#NUM!',
-0.73499999999999999,
2,
0.000146470701181,
8, 0,
],
[
'#NUM!',
0,
2,
0.000001308403709,
12.5, 0,
],
[
2.0790271499999999,
0.90000000000000002,
2,
0.000000000074124,
22, 0,
],
[
0.29690929999999999,
1.8999999999999999,
2,
0.000000000000003,
32, 0,
],
[
1632.1537072900001,
0.035000000000000003,
2,
7.83111830250218,
0.125, 1,
],
[
0.032307120000000002,
3.5,
2,
0.601907231666906,
1, 1,
],
[
0.017401429999999999,
4,
2,
0.073890815650267,
2.5, 1,
],
[
186560.35423214,
0.035000000000000003,
3,
0.022239393224641,
3.5, 1,
],
[
21.972169050000002,
0.69999999999999996,
3,
0.000155369216605,
8, 1,
],
[
10.31747315,
0.89000000000000001,
3,
0.000001359767834,
12.5, 1,
],
[
0.029884919999999999,
4,
3,
0.00000000007579,
22, 1,
],
[
0.15434255,
4,
5,
0.000000000000003,
32, 1,
],
[
2457.7004395499998,
1.5,
7,
127.505761924834,
0.125, 2,
],
[
397.95880105999998,
3,
9,
1.62483888441723,
1, 2,
],
[
0.121460206711233,
2.5, 2,
],
[
0.032307121670869,
3.5, 2,
],
[
0.000185313005332,
8, 2,
],
[
0.000001525966562,
12.5, 2,
],
[
0.000000000081014,
22, 2,
],
[
0.000000000000003,
32, 2,
],
[
12570631.999947274,
0.125, 5,
],
[
360.960586772793,
1, 5,
],
[
2.71688429212586,
2.5, 5,
],
[
0.364824403327597,
3.5, 5,
],
[
0.000619358014056,
8, 5,
],
[
0.00000339242503,
12.5, 5,
],
[
0.000000000128956,
22, 5,
],
[
0.000000000000004,
32, 5,
],
[
0.924419035021323,
0.5, 0.5,
],
[
1.65644112801108,
0.5, 1.5,
],
[
62.0579095045362,
0.5, 3.5,
],
[
0.0,
64, 8,
],
];

View File

@ -3,117 +3,174 @@
return [
[
'#NUM!',
1.5,
-1,
],
[
0.49807035999999999,
2.5,
0,
],
[
0.14591814,
2.5,
1,
],
[
-0.38133584999999998,
2.5,
2,
],
[
0.41018842,
3.5,
1,
],
[
-0.35833535,
3.5,
3,
],
[
0.045371439999999999,
3.5,
2,
],
[
-0.17121431000000001,
12.5,
0,
1.5, -1,
],
[
'#VALUE!',
1.5,
'XYZ',
'NaN', 1,
],
[
'#VALUE!',
'ABC',
3,
1.5, 'NaN',
],
[
'#NUM!',
-3.5,
1,
-1.5, 1,
],
[
'#NUM!',
-0.73499999999999999,
1,
0.0, 1,
],
[
'#NUM!',
0,
1,
'#VALUE!',
true, 1,
],
[
-0.41230863000000001,
1.5,
1,
'#VALUE!',
1.5, true,
],
[
0.14591814,
2.5,
1,
-1.38968063456627,
0.125, 0,
],
[
0.41018842,
3.5,
1,
0.088256971397708,
1, 0,
],
[
'#NUM!',
-9,
2,
0.498070358446689,
2.5, 0,
],
[
'#NUM!',
-0.73499999999999999,
2,
0.189021944512578,
3.5, 0,
],
[
'#NUM!',
0,
2,
0.223521489249681,
8, 0,
],
[
-1.9459096,
0.90000000000000002,
2,
-0.171214306884316,
12.5, 0,
],
[
-0.66987867999999995,
1.8999999999999999,
2,
0.119887597856641,
22, 0,
],
[
0.045371439999999999,
3.5,
2,
-0.028742484734472,
32, 0,
],
[
-0.79585141999999998,
4,
5,
-5.19993610955387,
0.125, 1,
],
[
-0.78121282095312,
1, 1,
],
[
0.145918137508313,
2.5, 1,
],
[
0.410188416627698,
3.5, 1,
],
[
-0.158060461835146,
8, 1,
],
[
-0.153838256351639,
12.5, 1,
],
[
0.123405856078544,
22, 1,
],
[
-0.138544831448816,
32, 1,
],
[
-81.8092971182956,
0.125, 2,
],
[
-1.65068261330395,
1, 2,
],
[
-0.381335848440038,
2.5, 2,
],
[
0.045371436417535,
3.5, 2,
],
[
-0.263036604708467,
8, 2,
],
[
0.146600185868054,
12.5, 2,
],
[
-0.108668883667682,
22, 2,
],
[
0.020083432768921,
32, 2,
],
[
-8018358.447601137,
0.125, 5,
],
[
-260.405867809914,
1, 5,
],
[
-3.83017599167454,
2.5, 5,
],
[
-1.14946031467642,
3.5, 5,
],
[
0.256401064838239,
8, 5,
],
[
-0.232903937762173,
12.5, 5,
],
[
0.16848172635078,
22, 5,
],
[
-0.139464153399118,
32, 5,
],
[
-0.444518733762708,
0.5, 0.5,
],
[
-1.47147239186729,
0.5, 1.5,
],
[
-42.0594942777845,
0.5, 3.5,
],
[
0.077260138596538,
64, 8,
],
];