math_calculation

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2025 License: MIT Imports: 11 Imported by: 0

README

Math Calculation

A high-performance, precise mathematical expression evaluation library for Go, supporting complex expressions, variables, and various mathematical functions.

Go Reference Go Report Card

Features

  • High Precision: Uses decimal package for accurate calculations without floating-point errors
  • Expression Evaluation: Parse and evaluate mathematical expressions with variables
  • Function Support: Built-in mathematical functions like sqrt, abs, pow, min, max, round, ceil, floor
  • Configurable Precision: Control precision and rounding modes
  • Performance Optimizations:
    • Expression caching
    • Lexer caching
    • Object pooling
    • Fast implementations of common math operations
  • Parallel Calculation: Evaluate multiple expressions in parallel
  • Compilation: Pre-compile expressions for repeated evaluation
  • Debugging: Detailed debugging information for complex expressions
  • Validation: Expression validation and sanitization

Installation

go get github.com/ZHOUXING1997/math_calculation

Quick Example

package main

import (
	"fmt"

	"github.com/ZHOUXING1997/math_calculation"
	"github.com/shopspring/decimal"
)

func main() {
	// Calculate a simple expression
	result, err := math_calculation.Calculate("sqrt(25) + 10", nil, nil)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Result: %s\n", result) // Output: Result: 15

	// Calculate with variables
	vars := map[string]decimal.Decimal{
		"x": decimal.NewFromFloat(5.0),
	}
	result, _ = math_calculation.Calculate("x * 2 + 3", vars, nil)
	fmt.Printf("x * 2 + 3 = %s\n", result) // Output: x * 2 + 3 = 13
}

Basic Usage

package main

import (
	"fmt"

	"github.com/shopspring/decimal"
	"github.com/ZHOUXING1997/math_calculation"
	"github.com/ZHOUXING1997/math_calculation/math_config"
)

func main() {
	// Define an expression
	expr := "sqrt(25) * (3.14 * x + 2.5) - abs(-5) + pow(2, 3)"

	// Define variables
	vars := map[string]decimal.Decimal{
		"x": decimal.NewFromFloat(5.0),
	}

	// Method 1: Simple API
	result, err := math_calculation.Calculate(expr, vars, math_config.NewDefaultCalcConfig())
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Result: %s\n", result)

	// Method 2: Fluent API
	calc := math_calculation.NewCalculator(nil)
	chainResult, err := calc.WithVariable("x", decimal.NewFromFloat(5.0)).Calculate(expr)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Chain API Result: %s\n", chainResult)
}

Advanced Features

Pre-compilation for Performance
// Create calculator
calc := math_calculation.NewCalculator(nil)
calc.WithVariable("x", decimal.NewFromFloat(5.0))

// Compile expression once
compiled, err := calc.Compile("sqrt(x) * (3.14 + 2.5)")
if err != nil {
    fmt.Printf("Compilation error: %v\n", err)
    return
}

// Evaluate multiple times with different variables
for i := 0; i < 1000; i++ {
    result, _ := compiled.Evaluate(map[string]decimal.Decimal{
        "x": decimal.NewFromFloat(float64(i)),
    })
    // Use result...
}
Parallel Calculation
expressions := []string{
    "sqrt(16) + 10",
    "pow(2, 8) / 4",
    "min(abs(-10), 5, 8)",
    "max(3 * 2, 7, 2 + 3)",
}

results, errs := math_calculation.NewCalculator(nil).
    WithVariable("x", decimal.NewFromFloat(5.0)).
    WithTimeout(time.Second * 10).
    CalculateParallel(expressions)

for i, result := range results {
    if errs[i] != nil {
        fmt.Printf("Expression %s failed: %v\n", expressions[i], errs[i])
    } else {
        fmt.Printf("Expression %s = %s\n", expressions[i], result)
    }
}
Precision Control
// Control precision mode
result, _ := math_calculation.NewCalculator(nil).
    WithPrecision(2).                    // Set precision to 2 decimal places
    WithPrecisionMode(math_config.CeilPrecision).  // Use ceiling rounding
    Calculate("1/3 + 1/3 + 1/3")

// Control when precision is applied
eachStepResult, _ := math_calculation.NewCalculator(nil).
    WithPrecisionEachStep().             // Apply precision at each calculation step
    Calculate("1/3 + 1/3 + 1/3")         // Typically results in 0.9999...

finalResult, _ := math_calculation.NewCalculator(nil).
    WithPrecisionFinalResult().          // Apply precision only to final result
    Calculate("1/3 + 1/3 + 1/3")         // Results in 1.0
Debugging
calc := math_calculation.NewCalculator(nil).
    WithDebugMode(math_config.DebugDetailed)

result, debugInfo, err := calc.CalculateWithDebug("1/3 + 1/3 + 1/3")
if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
}

fmt.Printf("Result: %s\n", result)
fmt.Printf("Expression: %s\n", debugInfo.Expression)
fmt.Printf("Variables: %v\n", debugInfo.Variables)

// Print calculation steps
for i, step := range debugInfo.Steps {
    fmt.Printf("Step %d: %s = %s\n", i+1, step.Operation, step.Result)
}

Supported Operations

Operators
  • Addition: +
  • Subtraction: -
  • Multiplication: *
  • Division: /
  • Power: ^ (integer exponents only)
  • Unary plus: +
  • Unary minus: -
Functions
  • sqrt(x) - Square root
  • abs(x) - Absolute value
  • pow(x, y) - Power (x raised to y)
  • min(x1, x2, ...) - Minimum value
  • max(x1, x2, ...) - Maximum value
  • round(x) - Round to nearest integer
  • round(x, n) - Round to n decimal places
  • ceil(x) - Ceiling (round up to nearest integer)
  • ceil(x, n) - Ceiling to n decimal places
  • floor(x) - Floor (round down to nearest integer)
  • floor(x, n) - Floor to n decimal places

Configuration Options

// Create custom configuration
config := &math_config.CalcConfig{
    MaxRecursionDepth:      100,           // Maximum recursion depth
    Timeout:                time.Second * 5, // Execution timeout
    Precision:              10,            // Decimal precision
    PrecisionMode:          math_config.RoundPrecision, // Rounding mode
    ApplyPrecisionEachStep: true,          // Apply precision at each step
    UseExprCache:           true,          // Use expression cache
    UseLexerCache:          true,          // Use lexer cache
    DebugMode:              math_config.DebugNone, // Debug mode
}

// Or use fluent API
calc := math_calculation.NewCalculator(nil).
    WithPrecision(10).
    WithPrecisionMode(math_config.RoundPrecision).
    WithTimeout(time.Second * 5).
    WithMaxRecursionDepth(100).
    WithCache().
    WithDebugMode(math_config.DebugNone)

Performance Considerations

  • Use pre-compilation for expressions that will be evaluated multiple times
  • Control cache sizes for optimal memory usage:
    math_calculation.SetLexerCacheCapacity(2000)
    math_calculation.SetExprCacheCapacity(3000)
    
  • For batch processing, use parallel calculation
  • Choose precision control strategy based on your needs:
    • WithPrecisionEachStep() for maximum control over potential overflow
    • WithPrecisionFinalResult() for more accurate results in some cases

Documentation

For detailed documentation and API reference, visit pkg.go.dev/github.com/ZHOUXING1997/math_calculation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License

Documentation

Overview

Example (Basic)

This example demonstrates how to use the basic Calculate function

package main

import (
	"fmt"

	"github.com/ZHOUXING1997/math_calculation"
)

func main() {
	// Calculate a simple expression
	result, err := math_calculation.Calculate("sqrt(25) + 10", nil, nil)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("Result: %s\n", result)

}
Output:

Result: 15
Example (Compilation)

This example demonstrates how to pre-compile expressions for better performance

package main

import (
	"fmt"

	"github.com/shopspring/decimal"

	"github.com/ZHOUXING1997/math_calculation"
)

func main() {
	// Create calculator
	calc := math_calculation.NewCalculator(nil)

	// Compile expression once
	compiled, err := calc.Compile("x^2 + 2*x + 1")
	if err != nil {
		fmt.Printf("Compilation error: %v\n", err)
		return
	}

	// Evaluate with different variables
	for i := 1; i <= 3; i++ {
		result, _ := compiled.Evaluate(map[string]decimal.Decimal{
			"x": decimal.NewFromInt(int64(i)),
		})
		fmt.Printf("When x=%d: (x^2 + 2*x + 1) = %s\n", i, result)
	}

}
Output:

When x=1: (x^2 + 2*x + 1) = 4
When x=2: (x^2 + 2*x + 1) = 9
When x=3: (x^2 + 2*x + 1) = 16
Example (FluentAPI)

This example demonstrates how to use the fluent API

package main

import (
	"fmt"

	"github.com/shopspring/decimal"

	"github.com/ZHOUXING1997/math_calculation"
)

func main() {
	// Create calculator with fluent API
	calc := math_calculation.NewCalculator(nil)

	// Set variables and configuration
	result, err := calc.
		WithVariable("x", decimal.NewFromFloat(5.0)).
		WithPrecision(2).
		WithRoundPrecision().
		WithPrecisionFinalResult().
		Calculate("sqrt(x) * 2")

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("sqrt(x) * 2 = %s\n", result)

}
Output:

sqrt(x) * 2 = 4.47
Example (PrecisionModes)

This example demonstrates how to use different precision modes

package main

import (
	"fmt"

	"github.com/ZHOUXING1997/math_calculation"
	"github.com/ZHOUXING1997/math_calculation/math_config"
)

func main() {
	expr := "1/3 + 1/3 + 1/3"

	// Round precision (default)
	round, _ := math_calculation.NewCalculator(nil).
		WithPrecision(2).
		WithPrecisionMode(math_config.RoundPrecision).
		WithPrecisionFinalResult().
		Calculate(expr)

	// Ceiling precision
	ceil, _ := math_calculation.NewCalculator(nil).
		WithPrecision(2).
		WithPrecisionMode(math_config.CeilPrecision).
		WithPrecisionFinalResult().
		Calculate(expr)

	// Floor precision
	floor, _ := math_calculation.NewCalculator(nil).
		WithPrecision(2).
		WithPrecisionMode(math_config.FloorPrecision).
		WithPrecisionFinalResult().
		Calculate(expr)

	fmt.Printf("Round: %s\n", round)
	fmt.Printf("Ceil: %s\n", ceil)
	fmt.Printf("Floor: %s\n", floor)

}
Output:

Round: 1
Ceil: 1
Floor: 0.99
Example (WithVariables)

This example demonstrates how to use variables in expressions

package main

import (
	"fmt"

	"github.com/shopspring/decimal"

	"github.com/ZHOUXING1997/math_calculation"
)

func main() {
	// Define variables
	vars := map[string]decimal.Decimal{
		"x": decimal.NewFromFloat(5.0),
		"y": decimal.NewFromFloat(3.0),
	}

	// Calculate expression with variables
	result, err := math_calculation.Calculate("x * y + 2", vars, nil)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	fmt.Printf("x * y + 2 = %s\n", result)

}
Output:

x * y + 2 = 17

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Calculate

func Calculate(expression string, vars map[string]decimal.Decimal, cfg *math_config.CalcConfig) (decimal.Decimal, error)

Calculate 计算表达式的便捷函数

func CalculateParallel

func CalculateParallel(expressions []string, vars map[string]decimal.Decimal, cfg *math_config.CalcConfig) ([]decimal.Decimal, []error)

CalculateParallel 并行计算多个表达式

func SetExprCacheCapacity

func SetExprCacheCapacity(capacity int)

func SetLexerCacheCapacity

func SetLexerCacheCapacity(capacity int)

Types

type Calculator

type Calculator struct {
	// contains filtered or unexported fields
}

Calculator 计算器结构体,支持链式API

func NewCalculator

func NewCalculator(cfg *math_config.CalcConfig) *Calculator

NewCalculator 创建新的计算器实例

func (*Calculator) Calculate

func (c *Calculator) Calculate(expression string) (decimal.Decimal, error)

Calculate 计算表达式

func (*Calculator) CalculateParallel

func (c *Calculator) CalculateParallel(expressions []string) ([]decimal.Decimal, []error)

CalculateParallel 并行计算多个表达式

func (*Calculator) CalculateWithDebug

func (c *Calculator) CalculateWithDebug(expression string) (decimal.Decimal, *debug.DebugInfo, error)

CalculateWithDebug 带调试信息的计算

func (*Calculator) Compile

func (c *Calculator) Compile(expression string) (*croe.CompiledExpression, error)

Compile 预编译表达式

func (*Calculator) GetLastDebugInfo

func (c *Calculator) GetLastDebugInfo() *debug.DebugInfo

GetLastDebugInfo 获取最后一次调试信息

func (*Calculator) WithCache

func (c *Calculator) WithCache() *Calculator

WithCache 启用缓存

func (*Calculator) WithCeilPrecision

func (c *Calculator) WithCeilPrecision() *Calculator

WithCeilPrecision 设置精度模式为向上取整

func (*Calculator) WithDebugMode

func (c *Calculator) WithDebugMode(mode math_config.DebugMode) *Calculator

WithDebugMode 设置调试模式

func (*Calculator) WithFloorPrecision

func (c *Calculator) WithFloorPrecision() *Calculator

WithFloorPrecision 设置精度模式为向下取整

func (*Calculator) WithMaxRecursionDepth

func (c *Calculator) WithMaxRecursionDepth(depth int) *Calculator

WithMaxRecursionDepth 设置最大递归深度

func (*Calculator) WithPrecision

func (c *Calculator) WithPrecision(precision int32) *Calculator

WithPrecision 设置精度

func (*Calculator) WithPrecisionEachStep

func (c *Calculator) WithPrecisionEachStep() *Calculator

WithPrecisionEachStep 在每一步应用精度控制

func (*Calculator) WithPrecisionFinalResult

func (c *Calculator) WithPrecisionFinalResult() *Calculator

WithPrecisionFinalResult 只在最终结果应用精度控制

func (*Calculator) WithPrecisionMode

func (c *Calculator) WithPrecisionMode(mode math_config.PrecisionMode) *Calculator

WithPrecisionMode 设置精度模式

func (*Calculator) WithRoundPrecision

func (c *Calculator) WithRoundPrecision() *Calculator

WithRoundPrecision 设置精度模式为四舍五入

func (*Calculator) WithTimeout

func (c *Calculator) WithTimeout(timeout time.Duration) *Calculator

WithTimeout 设置超时时间

func (*Calculator) WithTruncatePrecision

func (c *Calculator) WithTruncatePrecision() *Calculator

WithTruncatePrecision 设置精度模式为截断(直接截断,不进行舍入)

func (*Calculator) WithValidationOptions

func (c *Calculator) WithValidationOptions(options validator.ValidationOptions) *Calculator

WithValidationOptions 设置验证选项

func (*Calculator) WithVariable

func (c *Calculator) WithVariable(name string, value decimal.Decimal) *Calculator

WithVariable 添加变量

func (*Calculator) WithVariables

func (c *Calculator) WithVariables(vars map[string]decimal.Decimal) *Calculator

WithVariables 添加多个变量

func (*Calculator) WithoutCache

func (c *Calculator) WithoutCache() *Calculator

WithoutCache 禁用缓存

Directories

Path Synopsis
Package mathcalc 提供数学表达式解析和计算功能
Package mathcalc 提供数学表达式解析和计算功能

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL