avadim/ace-calculator

具有自定义操作符、函数和变量的灵活通用计算器

v3.1.2 2024-09-17 16:20 UTC

This package is auto-updated.

Last update: 2024-09-17 16:21:35 UTC


README

您可以使用变量计算经典数学表达式,或者您可以指定自己的计算规则、操作符或自定义函数

从NeonXP/MathExecutor (https://github.com/NeonXP/MathExecutor) 分支,但功能更加强大和改进。

跳转到

安装

|$ composer require avadim/ace-claculator

所有安装说明请见:https://packagist.org.cn/packages/avadim/ace-claculator

示例用法

require 'vendor/autoload.php';
// create the calculator
$calculator = new \avadim\AceClaculator\AceClaculator();

// calculate expression
print $calculator->execute('1 + 2 * (2 - (4+10))^2 + sin(10)');

// cascade execution - you can calculate a series of expressions 
// variable $_ has result of previous calculation
print $calculator
        ->calc('4+10')
        ->calc('1 + 2 * (2 - $_)^2') // the variable $_ contains the result of the last calculation
        ->calc('$_ + sin(10)')
        ->result();

默认操作符、函数和常数

默认操作符: + - * / ^

算术函数

  • abs()
  • avg()
  • ceil()
  • exp()
  • expm1()
  • floor()
  • fmod()
  • hypot()
  • intdiv()
  • log()
  • log10()
  • log1p()
  • max()
  • min()
  • sqrt()
  • round()

三角函数

  • acos()
  • acosh()
  • asin()
  • asinh()
  • atan()
  • atan2()
  • atanh()
  • atn() (atan的别名)
  • cos()
  • cosh()
  • deg2rad()
  • degrees() (rad2deg的别名)
  • rad2deg()
  • radians() (deg2rad的别名)
  • sin()
  • sinh()
  • tan()
  • tanh()
  • tn() (tan的别名)

默认常数

PI = 3.14159265358979323846 E = 2.7182818284590452354

您还可以使用PHP中的任何标准数学常数 - M_LOG2E, M_PI_2 等

$calculator->execute('cos(PI)');
$calculator->execute('cos(M_PI)'); // the same result

变量

您可以将自己的变量添加到执行器中并在表达式中使用它们

$calculator->setVars([
    'var1' => 0.15,
    'var2' => 0.22
]);

// calculation with variables
$calculator->execute('$var1 + $var2');

// calculate and assign result to $var3
$calculator->execute('$var1 + $var2', '$var3');

// assign values to variable in expression
$calculator
    ->calc('$var3 = ($var1 + $var2)')
    ->calc('$var3 * 20')
    ->result();

多个表达式

您可以通过分号分隔在一个中执行多个表达式

$result1 = $calculator
    ->setVar('$var1', 0.15)
    ->setVar('$var2', 0.22)
    ->calc('$var3 = $var1 + $var2')
    ->calc('$var3 * 20')
    ->result()
;
// $result2 will be equal $result1
$result2 = $calculator->execute('$var1=0.15; $var2=0.22; $var3 = $var1 + $var2; $var3 * 20');

额外操作符和函数

您可以通过方法 loadExtension() 加载带有额外操作符和函数的扩展

// load extension 'Bool'
$calculator->loadExtension('Bool');

此扩展加载布尔操作符:< <= > >= == != && ||

您可以使用额外函数 if() 使用布尔操作符

print $calculator->execute('if(100+20+3 > 111, 23, 34)');

自定义函数

向执行器添加自定义函数

$calculator->addFunction('dummy', function($a) {
    // do something
    return $result;
});

print $calculator->execute('dummy(123)');

// If the function takes more than 1 argument, you must specify this

// New function hypotenuse() with 2 arguments
$calculator->addFunction('hypotenuse', function($a, $b) {
    return sqrt($a^2 + $b^2);
}, 2);

// New function nround()
//   1 - minimum number of arguments
//   true - used optional arguments
$calculator->addFunction('nround', function($a, $b = 0) {
    return round($a,  $b);
}, 1, true);

print $calculator->execute('nround(hypotenuse(3,4), 2)');

自定义操作符

添加操作符的简单方法

use avadim\AceCalculator\Token\Operator\TokenOperator;
$func = function (array &$stack)
{
    $op2 = array_pop($stack);
    $op1 = array_pop($stack);
    
    return $op1->getValue() % $op2->getValue();
};

$calculator->addOperator('mod', [TokenOperator::MATH_PRIORITY_DIVIDE, $func]);
echo $calculator->execute('286 mod 100');

使用指定类添加操作符的另一种方法。创建自定义操作符的类

<?php
use avadim\AceCalculator\Generic\AbstractToken;
use avadim\AceCalculator\Generic\AbstractTokenOperator;
use avadim\AceCalculator\Token\TokenScalarNumber;

class TokenOperatorModulus extends AbstractTokenOperator
{
    protected static $pattern = 'mod';

    /**
     * Priority of this operator, more value is more priority 
     * (1 equals "+" or "-", 2 equals "*" or "/", 3 equals "^")
     * 
     * @return int
     */
    public function getPriority()
    {
        return 3;
    }

    /**
     * Association of this operator (self::LEFT_ASSOC or self::RIGHT_ASSOC)
     * @return string
     */
    public function getAssociation()
    {
        return self::LEFT_ASSOC;
    }

    /**
     * Execution of this operator
     * @param AbstractToken[] $stack Stack of tokens
     *
     * @return TokenScalarNumber
     */
    public function execute(&$stack)
    {
        $op2 = array_pop($stack);
        $op1 = array_pop($stack);
        $result = $op1->getValue() % $op2->getValue();

        return new TokenScalarNumber($result);
    }
}

并将该类添加到执行器中

$calculator = new avadim\AceClaculator\AceClaculator();
$calculator->addOperator('mod', \TokenOperatorModulus::class);
echo $calculator->execute('286 mod 100');

标识符的解析

标识符 - 以字母开头,由字母和数字的序列组成。您可以在计算中指定如何解析它们

$calculator->setIdentifiers([
    'ONE' => 1,
    'YEAR' => function($identifier) { return date('Y'); },
]);

$calculator->execute('YEAR + ONE');

非数值

非数值值将在算术操作中引起警告。但是,您可以设置一个特殊选项来避免这种情况。

$calculator = new avadim\AceCalculator\AceCalculator();

// calc expression with variable
$calculator->setVar('$x', null);
// There will be a warning in the next line
$calculator->execute('$x * 12');

$calculator->setOption('non_numeric', true);
// And now there will be no warning
$calculator->execute('$x * 12');

错误处理器

除以零

通常除以零会抛出 DivisionByZeroException。但您可以重新定义此行为

$s = '10/0';
$calculator->setDivisionByZeroHandler(static function($a, $b) {
    // $a and $b - the first and second operands
    return 0;
});
echo $calculator->execute($s);

未知标识符

通常未知标识符会抛出 UnknownIdentifier。但您可以重新定义此行为

$calculator->setIdentifiers([
    'ONE' => 1,
    'TWO' => 2,
]);

// Will throw an exception
echo $calculator->execute('THREE');

$calculator->setUnknownIdentifierHandler(static function($identifier) {
    return $identifier;
});
// Returns name of identifier as string 
echo $calculator->execute('THREE');

$calculator->setUnknownIdentifierHandler(static function($identifier) use ($calculator) {
    return $calculator->execute('ONE + TWO');
});
// Returns result of expression ONE + TWO
echo $calculator->execute('THREE');

未知变量

通常未知标识符会抛出 UnknownIdentifier。但您可以重新定义此行为

$calculator = new avadim\AceCalculator\AceCalculator();

// Will throw an exception
$calculator->execute('$a * 4');

// Now any undefined variables will be interpreted as 0
$calculator->setUnknownVariableHandler(static function($variable) {
    return 0;
});
$calculator->execute('$a * 4');

支持AceCalculator

如果您觉得这个包有用,您只需在Github上给我一个星标:)