maths

package module
v2.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2025 License: MIT Imports: 10 Imported by: 3

README

Maths Extension library

License Go Doc GitHub Release Conventional Commits Go Report Card codecov Build and test CodeQL Super Linter

codecov - svg

Documentation

Overview

Package maths provides basic mathematical functions and acts a supplement to the math package.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNegativeNumber is an error that indicates a negative number has been used where not permitted.
	ErrNegativeNumber = errors.New("number must be non-negative")

	// ErrOverflowDetected is an error that indicates an arithmetic overflow has been detected.
	ErrOverflowDetected = errors.New("arithmetic overflow detected")
)
View Source
var ErrAbsoluteValueOfMinInt = fmt.Errorf("can not calculate the absolute value of math.MinInt and store in an int variable: %w", ErrOverflowDetected)

ErrAbsoluteValueOfMinInt is an error that indicates an attempt to calculate the absolute value of math.MinInt and store it in an int variable, which is not possible due to overflow.

View Source
var ErrNLessThanK = errors.New("to calculate n choose k, n must be larger than or equal to k")

Functions

func Abs

func Abs(x int) (int, error)

Abs returns |x|. Returns an ErrAbsoluteValueOfMinInt error if calculating the absolute value of math.MinInt. In this case, consider *big.Int.Abs() from the math/big package.

Example
n := -10
absValue, err := Abs(n)
if err != nil {
	fmt.Println("Error:", err)
} else {
	fmt.Println("The absolute value of", n, "is", absValue)
}
Output:
The absolute value of -10 is 10

func Binomial

func Binomial(n, k int) (int, error)

Binomial returns the binomial coefficient of (n, k), n choose k, where n >= 0, k >= 0 and n >= k. It returns an ErrOverflowDetected error if the calculation results in an overflow. In this case, consider *big.Int.Binomial() from the math/big package.

Example
n, k := 10, 3
p, err := Binomial(n, k)
if err != nil {
	fmt.Printf("Error calculating the binomial coefficient of %d choose %d: %v\n", n, k, err)
} else {
	fmt.Printf("The binomial coefficient of %d choose %d is %d\n", n, k, p)
}

n, k = 70, 35
p, err = Binomial(n, k)
if err != nil {
	fmt.Printf("Error calculating the binomial coefficient of %d choose %d: %v\n", n, k, err)
} else {
	fmt.Printf("The binomial coefficient of %d choose %d is %d\n", n, k, p)
}
Output:
The binomial coefficient of 10 choose 3 is 120
Error calculating the binomial coefficient of 70 choose 35: the result of (70, 35) is too large to hold in an int variable: arithmetic overflow detected

func DigitsToBigInt added in v2.5.0

func DigitsToBigInt(x ...int) *big.Int

DigitsToBigInt returns a big.Int made from a concatenation of the given integers, in order. It will ignore any negative signs in the integers provided. If no integers are provided, it returns 0, big.NewInt(0).

Example
digits := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}

result := DigitsToBigInt(digits...)

fmt.Printf("The big integer from digits %v is %s\n", digits, result.String())
Output:
The big integer from digits [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] is 1234567891011121314151617181920

func DigitsToInt added in v2.5.0

func DigitsToInt(x ...int) (int, error)

DigitsToInt returns an int made from a concatenation of the given integers, in order. It will return an error if the concatenated digits exceed the range of an int. It will ignore any negative signs in the integers provided. If no integers are provided, it returns 0, nil.

Example
digits := []int{1, 2, 3, 4, 5}

result, err := DigitsToInt(digits...)
if err != nil {
	fmt.Printf("Error calculating the integer from digits %v: %v\n", digits, err)
} else {
	fmt.Printf("The integer from digits %v is %d\n", digits, result)
}
Output:
The integer from digits [1 2 3 4 5] is 12345

func Factorial

func Factorial(n int) (int, error)

Factorial returns the factorial of n, where n >= 0, with overflow detection. It returns an ErrOverflowDetected error if the calculation results in an overflow. If an overflow error is detected, the function returns 0, ErrOverflowDetected. In this case, consider *big.Int.MulRange() from the math/big package.

Example
n := 10
p, err := Factorial(n)
if err != nil {
	fmt.Printf("Error calculating the factorial of %d: %v\n", n, err)
} else {
	fmt.Printf("The factorial of %d is %d\n", n, p)
}

n = 21
p, err = Factorial(n)
if err != nil {
	fmt.Printf("Error calculating the factorial of %d: %v\n", n, err)
} else {
	fmt.Printf("The factorial of %d is %d\n", n, p)
}
Output:
The factorial of 10 is 3628800
Error calculating the factorial of 21: the result of 21! is too large to hold in an int variable: arithmetic overflow detected

func GCD

func GCD(numbers ...int) (int, error)

GCD returns the greatest common divisor of a group of integers i.e. the largest positive integer that divides each of the integers. This method uses the Euclidean algorithm. GCD() = GCD(0) = 0, nil. GCD(a, 0) = |a|, nil. It returns an error wrapping ErrOverflowDetected if the calculation results in an overflow. In this case, consider *big.Int.GCD() from the math/big package.

Example
m, n := 48, 18
gcd, err := GCD(m, n)
if err != nil {
	fmt.Printf("Error calculating the GCD of %d and %d: %v", m, n, err)
} else {
	fmt.Println("The GCD of", m, "and", n, "is", gcd)
}
Output:
The GCD of 48 and 18 is 6

func GetDigits

func GetDigits[T int | *big.Int](x T) []int

GetDigits returns a slice filled with the digits of x in the same order (starting with the largest magnitude numbers, left to right).

Example
ints := []int{12345, -12345, math.MaxInt, math.MinInt, 0}

for _, v := range ints {
	digits := GetDigits(v)
	fmt.Printf("The last digit of %d is %d\n", v, digits[len(digits)-1])
}
fmt.Println()

bigInts := []*big.Int{new(big.Int).SetBit(new(big.Int), 100, 1), new(big.Int).Exp(big.NewInt(3), big.NewInt(100), nil)}
for _, v := range bigInts {
	digits := GetDigits(v)
	fmt.Printf("The last digit of %d is %d\n", v, digits[len(digits)-1])
}
Output:
The last digit of 12345 is 5
The last digit of -12345 is 5
The last digit of 9223372036854775807 is 7
The last digit of -9223372036854775808 is 8
The last digit of 0 is 0

The last digit of 1267650600228229401496703205376 is 6
The last digit of 515377520732011331036461129765621272702107522001 is 1

func GetDivisors

func GetDivisors(x int) (<-chan int, error)

GetDivisors fills a channel with all the (positive) divisors of x, unsorted. Uses PrimeFactorisation().

Example
n := 28
divCh, err := GetDivisors(n)
if err != nil {
	fmt.Printf("Error calculating the divisors of %d: %v", n, err)
	return
}

divisors := make([]int, 0)
for d := range divCh {
	divisors = append(divisors, d)
}
fmt.Println("The divisors of", n, "are", divisors)
Output:
The divisors of 28 are [1 2 4 7 14 28]

func GetDivisorsBruteForce

func GetDivisorsBruteForce(x int) (<-chan int, error)

GetDivisorsBruteForce fills a channel with all the (positive) divisors of x, unsorted. Uses a brute force method.

Example
n := 30
divCh, err := GetDivisorsBruteForce(n)
if err != nil {
	fmt.Printf("Error calculating the divisors of %d: %v", n, err)
	return
}

divisors := make([]int, 0)
for d := range divCh {
	divisors = append(divisors, d)
}
slices.Sort(divisors)
fmt.Printf("The divisors of %d are %v", n, divisors)
Output:
The divisors of 30 are [1 2 3 5 6 10 15 30]

func GetPrimeNumbers

func GetPrimeNumbers(ctx context.Context) <-chan int

GetPrimeNumbers returns a channel from which to siphon off the prime numbers in order, as needed. Cancel the context when the calling function has finished with the return values and does not care about further possible values. The prime sieve: Daisy-chain Filter processes.

Example
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n := 40

primeCh := GetPrimeNumbers(ctx)
fmt.Printf("The first %d prime numbers are: ", n)
for range n {
	fmt.Printf("%d ", <-primeCh)
}
Output:
The first 40 prime numbers are: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173

func GetPrimeNumbersBelowAndIncluding

func GetPrimeNumbersBelowAndIncluding(ctx context.Context, n int) <-chan int

GetPrimeNumbersBelowAndIncluding fills a channel with the prime numbers below and including |n|, in order. Uses a euclidean sieve. Cancel the context when the calling function has finished with the return values and does not care about further possible values.

Example
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n := 50
primeCh := GetPrimeNumbersBelowAndIncluding(ctx, n)

fmt.Printf("The prime numbers below and including %d are: ", n)
for prime := range primeCh {
	fmt.Printf("%d ", prime)
}
Output:
The prime numbers below and including 50 are: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

func LCM

func LCM(numbers ...int) (int, error)

LCM returns the least common multiple of a group of integers i.e. the smallest positive integer that is divisible by each integer. This method uses GCD(). LCM() = LCM(0) = 0, nil. LCM(a, 0) = 0, nil. It returns an error wrapping ErrOverflowDetected if the calculation results in an overflow. In this case, consider LCMBig.

Example
m, n := 48, 18
lcm, err := LCM(m, n)
if err != nil {
	fmt.Printf("Error calculating the LCM of %d and %d: %v", m, n, err)
	return
} else {
	fmt.Println("The LCM of", m, "and", n, "is", lcm)
}
Output:
The LCM of 48 and 18 is 144

func LCMBig

func LCMBig(numbers ...*big.Int) *big.Int

LCMBig returns the least common multiple of a group of integers. This method uses *big.Int.GCD() from math/big. LCMBig() = LCM(0) = 0. LCM(a, 0) = 0.

Example
m, n := new(big.Int), big.NewInt(3)
m.SetString("10000000000000000000", 10)
lcm := LCMBig(m, n)
fmt.Println("The LCM of", m, "and", n, "is", lcm)
Output:
The LCM of 10000000000000000000 and 3 is 30000000000000000000

func Max

func Max[T cmp.Ordered](numbers ...T) T

Max returns the maximal value in a group of comparable values. It is a wrapper for the builtin slices.Max function.

Example
maxValue := Max(-100, -5, 0, 5, 10)
fmt.Println("The maximum value is", maxValue)
Output:
The maximum value is 10

func MaxPath

func MaxPath(t *Tree) int

MaxPath returns the largest of all the possible summations from top to bottom of a tree. The execution works up from the bottom of the pyramid. The maximum path to a node is the value of the node plus the maximum of the maximum paths to each child node. MaxPath(<nil>) returns 0.

func NumberOfDigits

func NumberOfDigits[T int | *big.Int](x T) int

NumberOfDigits returns the number of digits of an integer or big.Int. Uses integer-string conversion.

Example
ints := []int{12345, -12345, math.MaxInt, math.MinInt, 0, 1000000000, -1000000000, 99999999999999}

for _, v := range ints {
	fmt.Printf("Number of digits in %d: %d\n", v, NumberOfDigits(v))
}
fmt.Println()

bigInts := []*big.Int{new(big.Int).Exp(big.NewInt(10), big.NewInt(20), nil), new(big.Int).SetBit(new(big.Int), 100, 1)}
for _, v := range bigInts {
	fmt.Printf("Number of digits in %d: %d\n", v, NumberOfDigits(v))
}
Output:
Number of digits in 12345: 5
Number of digits in -12345: 5
Number of digits in 9223372036854775807: 19
Number of digits in -9223372036854775808: 19
Number of digits in 0: 1
Number of digits in 1000000000: 10
Number of digits in -1000000000: 10
Number of digits in 99999999999999: 14

Number of digits in 100000000000000000000: 21
Number of digits in 1267650600228229401496703205376: 31

func NumberOfDivisors

func NumberOfDivisors(x int) int

NumberOfDivisors returns the number of (positive) divisors of x. Uses PrimeFactorisation().

Example
n := 28
numDivisors := NumberOfDivisors(n)
fmt.Println("The number of divisors of", n, "is", numDivisors)
Output:
The number of divisors of 28 is 6

func NumberOfDivisorsBruteForce

func NumberOfDivisorsBruteForce(x int) int

NumberOfDivisorsBruteForce returns the number of (positive) divisors of x. Uses a brute force method.

Example
n := 28
numDivisors := NumberOfDivisorsBruteForce(n)
fmt.Println("The number of divisors of", n, "is", numDivisors)
Output:
The number of divisors of 28 is 6

func Pow

func Pow(x, y int) (int, error)

Pow returns the x^|y|. Returns 1, nil for all x and y when y is 0 or x is 1. It returns an error wrapping ErrOverflowDetected if the calculation results in an overflow. In this case, consider *big.Int.Exp() from the math/big package.

Example
m, n := 3, 5
result, err := Pow(m, n)
if err != nil {
	fmt.Printf("Error calculating %d^%d: %v", m, n, err)
} else {
	fmt.Printf("%d^%d = %d", m, n, result)
}
Output:
3^5 = 243

func PrimeFactorisation

func PrimeFactorisation(x int) <-chan PrimeFactor

PrimeFactorisation sends the prime factorisation of |x| on a channel, in order. If x is 0 or 1, PrimeFactorisation(x) returns a PrimeFactor with value x, index 1.

Example
input := 360
resultCh := PrimeFactorisation(input)

fmt.Printf("The prime factorisation of %d is: ", input)
for factor := range resultCh {
	fmt.Printf("%d^%d ", factor.Value, factor.Index)
}
Output:
The prime factorisation of 360 is: 2^3 3^2 5^1

func SumOfDivisors

func SumOfDivisors(x int) (int, error)

SumOfDivisors returns the sum of all the (positive) divisors of x. Uses PrimeFactorisation(). It returns an error wrapping ErrOverflowDetected if the calculation results in an overflow. In this case, you can try SumOfDivisorsBruteForce(), although this might still give an error.

Example
n := 28
sumDivisors, err := SumOfDivisors(n)
if err != nil {
	fmt.Printf("Error calculating the sum of the divisors of %d: %v", n, err)
} else {
	fmt.Println("The sum of the divisors of", n, "is", sumDivisors)
}

n = 3598428716789018112
sumDivisors, err = SumOfDivisors(n)
if err != nil {
	fmt.Printf("Error calculating the sum of the divisors of %d: %v", n, err)
} else {
	fmt.Println("The sum of the divisors of", n, "is", sumDivisors)
}
Output:
The sum of the divisors of 28 is 56
Error calculating the sum of the divisors of 3598428716789018112: failed to calculate 444879189109555200 * 42. The result is too large to hold in an int variable: arithmetic overflow detected

func SumOfDivisorsBruteForce

func SumOfDivisorsBruteForce(x int) (int, error)

SumOfDivisorsBruteForce returns the sum of all (positive) divisors of x. Uses GetDivisorsBruteForce(). It returns an error wrapping ErrOverflowDetected if the calculation results in an overflow.

Example
n := 28
sumDivisors, err := SumOfDivisorsBruteForce(n)
if err != nil {
	fmt.Printf("Error calculating the sum of the divisors of %d: %v", n, err)
} else {
	fmt.Println("The sum of the divisors of", n, "is", sumDivisors)
}

n = 3598428716789018112
sumDivisors, err = SumOfDivisorsBruteForce(n)
if err != nil {
	fmt.Printf("Error calculating the sum of the divisors of %d: %v", n, err)
} else {
	fmt.Println("The sum of the divisors of", n, "is", sumDivisors)
}
Output:
The sum of the divisors of 28 is 56
Error calculating the sum of the divisors of 3598428716789018112: failed to calculate 9060329447629492072 + 399825412976557568. The result is too large to hold in an int variable: arithmetic overflow detected

Types

type PrimeFactor

type PrimeFactor struct {
	Value, Index int
}

PrimeFactor is designed to hold a prime number as 'value' and the index of the prime number as it appears in a complete prime factorisation product.

type Tree

type Tree struct {
	Left  *Tree
	Value int
	Right *Tree
}

A Tree has a value and two sub trees.

func CreateBinaryTree

func CreateBinaryTree(values ...int) *Tree

CreateBinaryTree returns a (mostly) symmetric binary tree, filling with values from top to bottom, left to right. Each row has double the number of nodes as the previous row, starting with 1 node at the top. The tree is not guaranteed to be complete, so the last row may not be full. CreateBinaryTree() returns <nil>

func CreatePyramidTree

func CreatePyramidTree(values ...int) *Tree

CreatePyramidTree returns a (mostly) symmetric pyramid tree, filling with values from top to bottom, left to right. Each row has one more node than the previous row, starting with 1 node at the top. The tree is not guaranteed to be complete, so the last row may not be full. CreatePyramidTree() returns <nil>

func (*Tree) String added in v2.4.0

func (t *Tree) String() string

Jump to

Keyboard shortcuts

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