bigmath

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2025 License: Apache-2.0 Imports: 3 Imported by: 1

README

bigmath

Bigmath is a Go package that provides high-precision mathematical functions using Go's math/big library. It implements arbitrary-precision arithmetic methods that parallel much of what is found in the standard math package, enabling computations with hundreds or thousands of decimal places of precision.

Overview

The bigmath package extends Go's math/big capabilities by providing essential mathematical functions that operate on *big.Float and *big.Int types. This allows for computations that far exceed the precision limitations of standard floating-point types.

Features

  • High-precision arithmetic: Computations with configurable precision (typically 100-1000+ decimal places)
  • Mathematical constants: Pre-computed high-precision values of π and e
  • Well-tested: Extensive test coverage with validation against known mathematical constants and standard library methods.

Installation

go get github.com/rsned/bigmath

Quick Start

package main

import (
    "fmt"
    "math/big"
    "github.com/rsned/bigmath"
)

func main() {
    // Use pre-computed high-precision constants
    fmt.Printf("π = %s\n", bigmath.Pi().Text('f', 50))
    fmt.Printf("e = %s\n", bigmath.E().Text('f', 50))
    
    // Compute e^π with high precision
    x := bigmath.Pi()
    result := bigmath.Exp(x)
    fmt.Printf("e^π = %s\n", result.Text('f', 50))
    
    // Compute sqrt(2) with custom precision
    two := big.NewFloat(2).SetPrec(256)
    sqrt2 := bigmath.Sqrt(two)
    fmt.Printf("√2 = %s\n", sqrt2.Text('f', 50))
}

Available Functions

Mathematical Constants
  • Pi - Pre-computed π to 1000 decimal places
  • E - Pre-computed e to 1000 decimal places
Exponential and Logarithmic Functions
  • Exp(x *big.Float) *big.Float - Computes e^x using Taylor series expansion
  • Ln(x *big.Float) *big.Float - Natural logarithm using high-precision algorithms
  • Log(x *big.Float) (*big.Float, error) - Natural logarithm with error handling
Power Functions
  • Pow(x, y *big.Float) *big.Float - Computes x^y for arbitrary precision big.Floats
  • PowInt(x *big.Float, n int64) *big.Float - Optimized for integer exponentiation
  • PowFloat64(x, y float64) *big.Float - Convenience function for float64 inputs which would exceed math.MaxFloat64
  • Sqrt(x *big.Float) *big.Float - Square root using combination of methods.
Trigonometric Functions
  • Sin(x *big.Float) *big.Float - Sine

  • Cos(x *big.Float) *big.Float - Cosine

  • Tan(x *big.Float) *big.Float - Tangent

  • Secant(x *big.Float) *big.Float - Sine

  • Cosecant(x *big.Float) *big.Float - Cosine

  • Cotangent(x *big.Float) *big.Float - Tangent

  • Arcsin(x *big.Float) *big.Float - Sine⁻¹

  • Arccos(x *big.Float) *big.Float - Cosine⁻¹

  • Arctan(x *big.Float) *big.Float - Tangent⁻¹

  • Arcsec(x *big.Float) *big.Float - Secant⁻¹

  • Arccsc(x *big.Float) *big.Float - Cosecant⁻¹

  • Arccot(x *big.Float) *big.Float - Cotangent⁻¹

  • Sinh(x *big.Float) *big.Float - Hyperbolic Sine

  • Cosh(x *big.Float) *big.Float - Hyperbolic Cosine

  • Tanh(x *big.Float) *big.Float - Hyperbolic Tangent

  • Secanth(x *big.Float) *big.Float - Hyperbolic Secant

  • Cosecanth(x *big.Float) *big.Float - Cosine using Taylor series

  • Cotangenth(x *big.Float) *big.Float - Tangent using Taylor series

Gamma and Factorial Functions
  • Gamma(x *big.Float) *big.Float - Gamma function using Lanczos approximation
  • GammaFloat64(x float64) *big.Float - Convenience function for float64 input
  • Factorial(n int64) *big.Int - Integer factorial for large numbers
  • FactorialFloat(x *big.Float) *big.Float - Factorial for non-integers using Gamma function
  • FactorialInt(x int) *big.Float - Factorial for integer > 170 which would overflow normal math.
  • StirlingApproximation(x *big.Float) *big.Float - Stirling's approximation
High-Precision Constant Computation
  • ComputePi(precision uint) *big.Float - Compute π using Machin's formula with the given bits of precision.
  • ComputeE(precision uint) *big.Float - Compute e using series expansion with the given bits of precision.
  • ComputeLn2(precision uint) *big.Float - Compute ln(2) with high precision with the given bits of precision.

Precision and Performance

The package is designed to handle computations with:

  • 100+ decimal places: Typical use cases with good performance
  • 1000+ decimal places: Advanced applications with reasonable performance
  • Custom precision: Configurable precision based on application needs
Performance Characteristics

Some example timings on a moderate system (i7700)

  • ComputeE: ~28μs (100 digits) to ~1ms (2000 digits)
  • ComputePi: ~22μs (100 digits) to ~2ms (2000 digits)
  • Exp: ~36μs (small values) to ~480μs (large values)

Accuracy

The package provides excellent accuracy:

  • e computation: Accurate to at least 350 decimal places
  • π computation: Accurate to at least 700 decimal places
  • Exponential function: Relative error < 1e-70 for typical inputs
  • Other functions: Generally accurate to hundreds of decimal places

Examples

Computing Mathematical Constants
// Compute π to 500 decimal places
pi500 := bigmath.ComputePi(2000) // ~2000 bits ≈ 600 decimal places
fmt.Printf("π = %s\n", pi500.Text('f', 500))

// Compute e to 200 decimal places  
e200 := bigmath.ComputeE(800)
fmt.Printf("e = %s\n", e200.Text('f', 200))
High-Precision Calculations
// Compute e^(π*i) + 1 ≈ 0 (Euler's identity, imaginary part omitted)
pi := new(big.Float).Copy(bigmath.Pi)
ePi := bigmath.Exp(pi)
fmt.Printf("e^π = %s\n", ePi.Text('f', 50))

// Compute 2^100 exactly
base := big.NewFloat(2)
exp := int64(100)
result := bigmath.PowInt(base, exp)
fmt.Printf("2^100 = %s\n", result.Text('f', 0))
Gamma Function Applications
// Compute Γ(0.5) = √π
x := big.NewFloat(0.5).SetPrec(256)
gamma := bigmath.Gamma(x)
fmt.Printf("Γ(0.5) = %s\n", gamma.Text('f', 50))

// Compute 100!
factorial100 := bigmath.Factorial(100)
fmt.Printf("100! = %s\n", factorial100.String())

Testing and Benchmarking

The package includes comprehensive tests validating accuracy against known mathematical constants and comparing results with reference implementations.

go test ./...                    # Run all tests
go test --timeout=10m -bench=.   # Run all benchmarks (may need to adjust the timeout)
go test -run TestComputeE -v     # Test e computation specifically
Tests

Most methods have basic tests along with related unit tests comparing the results to other systems or sources on common sets of inputs.

Benchmarks

In addition to basic Benchmarks (e.g., BenchmarkSin), for most methods, there are additional benchmarks that test over a few common ranges of precision bits (53, 64, 128, 256, 500, 1000, 2000) to better measure the impact of increasing precision.

For many of the methods, I've included more than one common implementation method to better gauge which algorithm is the better choice. For example, in log.go, there are three implementations, logNewton, logHalley, and logTaylor.

License

Apache 2.0

See Also

Documentation

Overview

Package bigmath implements arbitrary-precision arithmetic (big numbers) methods to parallel much of what is found in [https://pkg.go.dev/math](math)

Index

Constants

This section is empty.

Variables

View Source
var (
	BernoulliNumbers = []big.Float{
		*big.NewFloat(1),
		*big.NewFloat(1.0 / 2),
		*big.NewFloat(1.0 / 6),
		*big.NewFloat(-1.0 / 30),
		*big.NewFloat(1.0 / 42),
		*big.NewFloat(-1.0 / 30),
		*big.NewFloat(5.0 / 66),
		*big.NewFloat(-691.0 / 2730),
		*big.NewFloat(7.0 / 6),
		*big.NewFloat(-3617.0 / 510),
		*big.NewFloat(43867.0 / 798),
		*big.NewFloat(-174611.0 / 330),
		*big.NewFloat(854513.0 / 138),
		*big.NewFloat(-236364091.0 / 2730),
		*big.NewFloat(8553103.0 / 6),
		*big.NewFloat(-23749461029.0 / 870),
		*big.NewFloat(8615841276005.0 / 14322),
		*big.NewFloat(-7709321041217.0 / 510),
		*big.NewFloat(2577687858367.0 / 6),
		*big.NewFloat(-26315271553053477373.0 / 1919190),
		*big.NewFloat(2929993913841559.0 / 6),
		*big.NewFloat(-261082718496449122051.0 / 13530),
		*big.NewFloat(1520097643918070802691.0 / 1806),
		*big.NewFloat(-27833269579301024235023.0 / 690),
		*big.NewFloat(596451111593912163277961.0 / 282),
		*big.NewFloat(-5609403368997817686249127547.0 / 46410),
		*big.NewFloat(495057205241079648212477525.0 / 66),
		*big.NewFloat(-801165718135489957347924991853.0 / 1590),
		*big.NewFloat(29149963634884862421418123812691.0 / 798),
		*big.NewFloat(-2479392929313226753685415739663229.0 / 870),
		*big.NewFloat(84483613348880041862046775994036021.0 / 354),
		*big.NewFloat(-1215233140483755572040304994079820246041491.0 / 56786730),
	}
)

Bernoulli B2n numbers are used in some Taylor series expansions.

Functions

func Acos

func Acos(x *big.Float) *big.Float

Acos returns the arccosine, in radians, of x.

The special case is:

Acos(x) = NaN if x < -1 or x > 1

func Acosh

func Acosh(x *big.Float) *big.Float

Acosh returns the inverse hyperbolic cosine of x.

The special cases are:

Acosh(+Inf) = +Inf
Acosh(x) = NaN if x < 1
Acosh(NaN) = NaN

func Acot

func Acot(x *big.Float) *big.Float

Acot calculates inverse cotangent using the identity acot(x) = π/2 - atan(x).

func Acoth

func Acoth(x *big.Float) *big.Float

Acoth calculates inverse hyperbolic cotangent using the formula: acoth(x) = atanh(1/x) This is a placeholder implementation.

func Acsc

func Acsc(x *big.Float) *big.Float

Acsc calculates inverse cosecant using the identity acsc(x) = asin(1/x).

func Acsch

func Acsch(x *big.Float) *big.Float

Acsch calculates inverse hyperbolic cosecant using the formula: acsch(x) = asinh(1/x) This is a placeholder implementation.

func Asec

func Asec(x *big.Float) *big.Float

Asec calculates inverse secant using the identity asec(x) = acos(1/x).

func Asech

func Asech(x *big.Float) *big.Float

Asech calculates inverse hyperbolic secant using the formula: asech(x) = acosh(1/x) This is a placeholder implementation.

func Asin

func Asin(x *big.Float) *big.Float

Asin returns the arcsine, in radians, of x.

The special cases are:

Asin(±0) = ±0
Asin(x) = NaN if x < -1 or x > 1

func Asinh

func Asinh(x *big.Float) *big.Float

Asinh returns the hyperbolic sine of x.

The special cases are:

Asinh(±0) = ±0
Asinh(±Inf) = ±Inf
Asinh(NaN) = NaN

func Atan

func Atan(x *big.Float) *big.Float

Atan returns the arctangent, in radians, of x.

The special cases are:

Atan(±0) = ±0
Atan(±Inf) = ±Pi/2
Atan(NaN) = NaN

func Atanh

func Atanh(x *big.Float) *big.Float

Atanh returns the inverse hyperbolic arc tangent of x.

The special cases are:

Atanh(1) = +Inf
Atanh(±0) = ±0
Atanh(-1) = -Inf
Atanh(x) = NaN if x < -1 or x > 1
Atanh(NaN) = NaN

func ComputeE

func ComputeE(precision uint) *big.Float

ComputeE calculates e with the given precision using series expansion

func ComputePi

func ComputePi(precision uint) *big.Float

ComputePi calculates π with the given precision using Machin's formula

func Cos

func Cos(x *big.Float) *big.Float

Cos returns the cosine of the radian argument x.

The special cases are:

Cos(±Inf) = NaN
Cos(NaN) = NaN

func Cosh

func Cosh(x *big.Float) *big.Float

Cosh returns the hyperbolic cosine of x.

The special cases are:

Cosh(±0) = 1
Cosh(±Inf) = +Inf
Cosh(NaN) = NaN

func Cot

func Cot(x *big.Float) *big.Float

Cot calculates cot(x) as cos(x)/sin(x).

func Coth

func Coth(x *big.Float) *big.Float

Coth calculates hyperbolic cotangent using the formula: coth(x) = cosh(x)/sinh(x) This is a placeholder implementation.

func Csc

func Csc(x *big.Float) *big.Float

Csc calculates cosecant as 1/sin(x).

func Csch

func Csch(x *big.Float) *big.Float

Csch calculates hyperbolic cosecant using the formula: csch(x) = 1/sinh(x) This is a placeholder implementation.

func E

func E() *big.Float

E returns a copy of the precomputed high-precision e value.

Because we can't make const *big.Floats, and don't want someone downstream altering the value, we return a copy.

func Exp

func Exp(x *big.Float) *big.Float

Exp returns e**x, the base-e exponential of x.

The special cases are:

Exp(+Inf) = +Inf
Exp(NaN) = NaN

Very large values no longer overflow to 0 or +Inf. Very small values no longer underflow to 1.

For the time being, there is an explicit upper bound for x of ~700,000 beyond which we choose to call it Infinite instead of looping excessively.

func Exp2

func Exp2(x *big.Float) *big.Float

Exp2 returns 2**x, the base-2 exponential of x.

The special cases are:

Exp2(+Inf) = +Inf
Exp2(NaN) = NaN

func Factorial

func Factorial(n int64) *big.Int

Factorial calculates n! using big.Int math to ensure no overflow.

big.Int does not have a concept of Inf or NaN, so the best we can do for negatives is return 0.

func FactorialFloat

func FactorialFloat(x *big.Float) *big.Float

FactorialFloat is a function that returns the factorial of a given big.Float. For integer values, computes n! = n * (n-1) * ... * 2 * 1 For non-integer values, uses the Gamma function property: n! = Gamma(n+1)

Negative values will return +Inf.

func Gamma

func Gamma(x *big.Float) *big.Float

Gamma returns the Gamma function of x using *big.Float arithmetic.

For positive integers n, Γ(n) = (n-1)!

Uses Stirling's approximation for large values and Lanczos approximation for smaller values.

The special cases are:

Gamma(+Inf) = +Inf
Gamma(+0) = +Inf
Gamma(-0) = -Inf
Gamma(x) = NaN for integer x < 0
Gamma(-Inf) = NaN
Gamma(NaN) = NaN

func GammaFloat64

func GammaFloat64(x float64) *big.Float

GammaFloat64 computes the Gamma function Γ(x) by converting the float64 to a *big.Float and then using the Gamma() method for values that would otherwise have led to overflow in float64.

For positive integers n, Γ(n) = (n-1)!

func Log

func Log(x *big.Float) *big.Float

Log computes natural logarithm using a collection of methods depending in the input value and precision.

func Pi

func Pi() *big.Float

Pi returns a copy of the precomputed high-precision π value.

Because we can't make const *big.Floats, and don't want someone downstream altering the value, we return a copy.

func Pow

func Pow(x, y *big.Float) *big.Float

Pow returns x**y, the base-x exponential of y using *big.Float arithmetic.

Special cases are (in order):

Pow(x, ±0) = 1 for any x Pow(1, y) = 1 for any y Pow(x, 1) = x for any x Pow(NaN, y) = NaN Pow(x, NaN) = NaN Pow(±0, y) = ±Inf for y an odd integer < 0 Pow(±0, -Inf) = +Inf Pow(±0, +Inf) = +0 Pow(±0, y) = +Inf for finite y < 0 and not an odd integer Pow(±0, y) = ±0 for y an odd integer > 0 Pow(±0, y) = +0 for finite y > 0 and not an odd integer Pow(-1, ±Inf) = 1 Pow(x, +Inf) = +Inf for |x| > 1 Pow(x, -Inf) = +0 for |x| > 1 Pow(x, +Inf) = +0 for |x| < 1 Pow(x, -Inf) = +Inf for |x| < 1 Pow(+Inf, y) = +Inf for y > 0 Pow(+Inf, y) = +0 for y < 0 Pow(-Inf, y) = Pow(-0, -y) Pow(x, y) = NaN for finite x < 0 and finite non-integer y

func PowFloat64

func PowFloat64(x, y float64) *big.Float

PowFloat64 returns x**y, the base-x exponential of y from float64 inputs returning a *big.Float. Useful when x**y would overflow a float64 normally.

Special cases are:

PowFloat64(x, ±0) = 1 for any x PowFloat64(1, y) = 1 for any y PowFloat64(x, 1) = x for any x PowFloat64(NaN, y) = ErrNaN PowFloat64(x, NaN) = ErrNaN Pow(±0, -Inf) = +Inf Pow(±0, +Inf) = +0 Pow(±0, y) = +Inf for finite y < 0 and not an odd integer Pow(±0, y) = +0 for finite y > 0 and not an odd integer Pow(±0, y) = ±Inf for y an odd integer < 0 Pow(±0, y) = ±0 for y an odd integer > 0 Pow(-1, ±Inf) = 1 Pow(x, +Inf) = +Inf for |x| > 1 Pow(x, -Inf) = +0 for |x| > 1 Pow(x, +Inf) = +0 for |x| < 1 Pow(x, -Inf) = +Inf for |x| < 1 Pow(+Inf, y) = +Inf for y > 0 Pow(+Inf, y) = +0 for y < 0 Pow(-Inf, y) = Pow(-0, -y) Pow(x, y) = ErrNan for finite x < 0 and finite non-integer y

func PowInt

func PowInt(x *big.Float, n int64) *big.Float

PowInt returns x**n for integer exponent n using repeated multiplication.

func Sec

func Sec(x *big.Float) *big.Float

Sec calculates sec(x) as 1/cos(x).

func Sech

func Sech(x *big.Float) *big.Float

Sech calculates hyperbolic secant using the formula: sech(x) = 1/cosh(x) This is a placeholder implementation.

func Sin

func Sin(x *big.Float) *big.Float

Sin returns the sine of the radian argument x.

Choose the best available algorithm for maximum precision. Automatically selects between Taylor series, Chebyshev polynomials, minimax approximation, and CORDIC based on argument size and precision requirements.

The special cases are:

Sin(±0) = ±0
Sin(±Inf) = NaN
Sin(NaN) = NaN

func Sinh

func Sinh(x *big.Float) *big.Float

Sinh returns the hyperbolic sine of x.

The special cases are:

Sinh(±0) = ±0
Sinh(±Inf) = ±Inf
Sinh(NaN) = NaN

func Tan

func Tan(x *big.Float) *big.Float

Tan returns the tangent of the radian argument x.

The special cases are:

Tan(±0) = ±0
Tan(±Inf) = NaN
Tan(NaN) = NaN

func Tanh

func Tanh(x *big.Float) *big.Float

Tanh returns the hyperbolic tangent of x.

The special cases are:

Tanh(±0) = ±0
Tanh(±Inf) = ±1
Tanh(NaN) = NaN

Types

This section is empty.

Jump to

Keyboard shortcuts

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