Documentation
¶
Overview ¶
Package math provides useful math functions
SPDX-License-Identifier: Apache-2.0
Index ¶
- Variables
- func Abs[T constraint.Numeric](val *T) error
- func AddInt[T constraint.SignedInteger](ae1 T, ae2 *T) error
- func AddUint[T constraint.UnsignedInteger](ae1 T, ae2 *T) error
- func AdjustDecimalFormat(d1, d2 Decimal) (string, string)
- func AdjustDecimalScale(d1, d2 *Decimal) error
- func CmpComplex[T constraint.Complex](val1, val2 T) (res int)
- func CmpOrdered[T constraint.Ordered](val1, val2 T) (res int)
- func Div[T constraint.Numeric](dividend T, divisor T, quotient *T) error
- func DivBigOps[T constraint.BigOps[T]](dividend T, divisor T, quotient *T) error
- func MaxCmp[T constraint.Cmp[T]](val1, val2 T) T
- func MaxComplex[T constraint.Complex](val1, val2 T) T
- func MaxOrdered[T constraint.Ordered](val1, val2 T) T
- func MinCmp[T constraint.Cmp[T]](val1, val2 T) T
- func MinComplex[T constraint.Complex](val1, val2 T) T
- func MinOrdered[T constraint.Ordered](val1, val2 T) T
- func Mul[T constraint.Integer](mp T, ma *T) error
- func MustAdjustDecimalScale(d1, d2 *Decimal)
- func SubInt[T constraint.SignedInteger](me T, sed *T) error
- func SubUint[T constraint.UnsignedInteger](me T, sed *T) error
- type Decimal
- func (d Decimal) Add(o Decimal) (Decimal, error)
- func (d Decimal) Cmp(o Decimal) int
- func (d Decimal) Div(o Decimal) (Decimal, error)
- func (d Decimal) DivIntAdd(o uint) ([]Decimal, error)
- func (d Decimal) DivIntQuoRem(o uint) (Decimal, Decimal, error)
- func (d Decimal) MagnitudeLessThanOne() bool
- func (d Decimal) Mul(o Decimal) (Decimal, error)
- func (d Decimal) MustAdd(o Decimal) Decimal
- func (d Decimal) MustDiv(o Decimal) Decimal
- func (d Decimal) MustDivIntAdd(o uint) []Decimal
- func (d Decimal) MustDivIntQuoRem(o uint) (Decimal, Decimal)
- func (d Decimal) MustMul(o Decimal) Decimal
- func (d Decimal) MustSub(o Decimal) Decimal
- func (d Decimal) Negate() Decimal
- func (d *Decimal) Normalize()
- func (d Decimal) Normalized() bool
- func (d Decimal) Precision() int
- func (d Decimal) Scale() uint
- func (d Decimal) Sign() (sgn int)
- func (d Decimal) String() (str string)
- func (d Decimal) Sub(o Decimal) (Decimal, error)
- type Range
- type RangeMode
Constants ¶
This section is empty.
Variables ¶
var ( OverflowErr = fmt.Errorf("Overflow error") UnderflowErr = fmt.Errorf("Underflow error") DivByZeroErr = fmt.Errorf("Division by zero error") )
Constants
Functions ¶
func Abs ¶
func Abs[T constraint.Numeric](val *T) error
Abs calculates the absolute value of any numeric type. Integer types have a range of -N ... +(N-1), which means that if you try to calculate abs(-N), the result is -N. The reason for this is that there is no corresponding +N, that would require more bits. In this special case, an error is returned, otherwise nil is returned. Note that while the constraint allows unsigned ints for completeness, no operation is performed.
func AddInt ¶
func AddInt[T constraint.SignedInteger](ae1 T, ae2 *T) error
AddInt adds two signed integers overwriting the second value, and returns an error if over/underflow occurs. Over/underflow occurrs if two numbers of the same sign are added, and the sign of result has changed. EG, two positive ints are added to create a result too large to be represented in the same number of bits,
or two negative ints are added to create a result too small to be represented in the same number of bits.
func AddUint ¶
func AddUint[T constraint.UnsignedInteger](ae1 T, ae2 *T) error
AddUint adds two unsigned integers overwriting the second value, and returns an error if overflow occurs. Overflow occurs if two numbers are added, and the magnitude of result is smaller.
func AdjustDecimalFormat ¶
AdjustDecimalFormat adjusts the two decimals strings to have the same number of digits before the decimal, and the same number of digits after the decimal. Leading and trailing zeros are added as needed. A positive number has a leading space.
The strings returned are not directly comparable numerically: "-1" > " 1" "-2" > "-1"
Examples: 30, 5 -> " 30", " 05" 1.23, -78.295 -> " 01.230", "-78.295"
func AdjustDecimalScale ¶
AdjustDecimalScale adjusts the scale of d1 and d2:
- If both numbers have the same scale, no adjustment is made
- Otherwise, the number with the smaller scale is usually adjusted to the same scale as the other number
- Increasing the scale can cause some most significant digits to be lost, in which case the other number is rounded down to match the scale
Examples:
1.5 and 1.25 -> 1.50 and 1.25 1.5 and 18 digits with no decimals -> 18 digits cannot increase scale, so round 1.5 to 2 99_999_999_999_999_999.5 and 1 -> the 18 digits round to a 19 digit value, an error occurs
func CmpComplex ¶
func CmpComplex[T constraint.Complex](val1, val2 T) (res int)
CmpComplex compares two complex types and returns -1, 0, 1, depending on whether val1 is <, =, or > val2.
func CmpOrdered ¶
func CmpOrdered[T constraint.Ordered](val1, val2 T) (res int)
CmpOrdered compares two ordered types and returns -1, 0, 1, depending on whether val1 is <, =, or > val2.
func Div ¶
func Div[T constraint.Numeric](dividend T, divisor T, quotient *T) error
Div calculates the quotient of a division operation of a pair of integers or a pair of floating point types. In the case of integers, the remainder is handled as follows: - If the divisor is even, and abs(remainder) >= abs(divisor) / 2, then increase magnitude of quotient by one. - If the divisor is odd, and abs(remainder) > abs(divisor) / 2, then increase magnitude of quotient by one.
Increasing the magnitude by one means add one of the quotient is positive, subtract one if negative. The purpose of adjusting the magnitude is to get the same result as rounding the floating point calculation. Floats are not used since 32 and 64 bit integer values can have a magnitude too large to be expressed accurately in a float.
Integer Examples: 18 / 4 = 4 remainder 2. Since divisor 4 is even and remainder 2 is >= (4 / 2 = 2), increment quotient to 5 (round 4.5 up). 17 / 5 = 3 remainder 2. Since divisor 5 is odd and remainder 2 is not > (5 / 2 = 2), leave quotient as is (round 3.4 down).
func DivBigOps ¶
func DivBigOps[T constraint.BigOps[T]](dividend T, divisor T, quotient *T) error
DivBigOps is the BigOps version of Div
func MaxCmp ¶
func MaxCmp[T constraint.Cmp[T]](val1, val2 T) T
MaxCmp returns the maximum value of two comparable types
func MaxComplex ¶
func MaxComplex[T constraint.Complex](val1, val2 T) T
MaxComplex returns the maximum value of two complex types
func MaxOrdered ¶
func MaxOrdered[T constraint.Ordered](val1, val2 T) T
MaxOrdered returns the maximum value of two ordered types
func MinCmp ¶
func MinCmp[T constraint.Cmp[T]](val1, val2 T) T
MinCmp returns the minimum value of two comparable types
func MinComplex ¶
func MinComplex[T constraint.Complex](val1, val2 T) T
MinComplex returns the minimum value of two complex types
func MinOrdered ¶
func MinOrdered[T constraint.Ordered](val1, val2 T) T
MinOrdered returns the minimum value of two ordered types
func Mul ¶
func Mul[T constraint.Integer](mp T, ma *T) error
Mul multiples two integers overwriting the second value, and returns an error if over/underflow occurs. Over/underflow occurs if the magnitude of the result requires more bits than the type provides. Unsigned types can only overflow.
func MustAdjustDecimalScale ¶
func MustAdjustDecimalScale(d1, d2 *Decimal)
MustAdjustDecimalScale is a must version of AdjustDecimalScale
func SubInt ¶
func SubInt[T constraint.SignedInteger](me T, sed *T) error
SubInt subtracts two integers as sed = me - sed, overwriting the second value, and returns an error if over/underflow occurs. See AddInt.
func SubUint ¶
func SubUint[T constraint.UnsignedInteger](me T, sed *T) error
SubUint subtracts two integers as sed = me - sed, overwriting the second value, and returns an error if underflow occurs. Underflow occurs if sed > me before the subtraction is performed.
Types ¶
type Decimal ¶
type Decimal struct {
// contains filtered or unexported fields
}
Decimal is like SQL Decimal(precision, scale): - precision is always 18, the maximum number of decimal digits a signed 64 bit value can store - scale is number of digits after decimal place, must be <= 18 (default 2 as most popular use is money)
The zero value is ready to use
func MustDecimal ¶
MustDecimal is a must version of OfDecimal
func MustStringToDecimal ¶
MustStringToDecimal is a must version of StringToDecimal
func OfDecimal ¶
OfDecimal creates a Decimal with the given sign, digits, and scale For clarity, there is no default scale
func StringToDecimal ¶
StringToDecimal creates a Decimal from the given string The string must contain no more than 18 significant digits, and satisfy the following regex: (-?)([0-9]*)(.[0-9]*)?
func (Decimal) Add ¶
Add adds two decimals together by first adjusting them to the same scale, then adding their values Returns an error if: - Adjusting the scale produces an error - Addition overflows or underflows
See addDecimal
func (Decimal) Cmp ¶
Cmp compares d against o, and returns -1, 0, or 1 depending on whether d < o, d = o, or d > o, respectively.
func (Decimal) Div ¶
Div is the general form of division, suitable for any two Decimal values. Integer division is used to generate digits by taking remainders and multiplying them by 10 until they are >= divisor, so that the remainder can then be divided further, generating more digits.
Examples:
1. 5000 / 200 5000 / 200 = 25
2. 500.0 / 200 5000 / 200 = 25 Scale 1 - scale 0 = 1 -> Set scale to 1 Result is 2.5
3. 500.0 / 2.00 5000 / 200 = 25 Scale 1 - scale 2 = -1 -> Multiply by 10^1 Result is 250
4. 500.1 / 2.00 5001 / 200 = 25 r 1 Scale 1 - scale 2 = -1 -> Multiply by 10^1 250 r 10 10 / 200 -> 1000 (10 * 10^2) / 200 = 5 scale 2 = 0.05 Result is 250.05
5. 5001 / 200 5001 / 200 = 25 r 1 1 / 200 -> 1000 (1 * 10^3) / 200 = 5 scale 3 = 0.005 Result is 25 + 0.005 = 25.005
6. 5001 / -200 5001 / -200 = -25 r 1 1 / -200 -> 1000 (1 * 10^3) / -200 = -5 scale 3 = -0.005 Result is -25 + -0.005 = -25.005
7. -5001 / 200 -5001 / 200 = -25 r -1 -1 / 200 -> -1000 (1 * 10^3) / 200 = -5 scale 3 = -0.005 Result is -25 + -0.005 = -25.005
8. -5001 / -200 -5001 / -200 = 25 r -1 Adjust remainder sign to 1 1 / 200 -> 1000 (1 * 10^3) / 200 = 5 scale 3 = 0.005 Result is 25 + 0.005 = 25.005
9. -500.1 / 200 -5001 / 200 = -25 r -1 Scale 1 - scale 0 = 1 -> -25 scale 1 = -2.5 -1 / 200 -> -1000 (1 * 10^3) / 200 = -5 scale (1 + 3) = -0.0005 Result is -2.5 + -0.0005 = -2.5005
10. 3 / 2 3 / 2 = 1 r 1 1 / 2 = 10 (1 * 10^1) / 2 = 5 scale 1 Result is 1.5
10. 5.123 / 0.021 5123 / 21 = 243 r 20
20 / 21 = 200 (20 * 10^1) / 21 = 9 scale 1 + 0 r 11 = 0.9 r 11 11 / 21 = 110 (11 * 10^1) / 21 = 5 scale 1 + 1 r 5 = 0.05 r 5 5 / 21 = 50 (5 * 10^1) / 21 = 2 scale 1 + 2 r 8 = 0.002 r 8 8 / 21 = 80 (8 * 10^1) / 21 = 3 scale 1 + 3 r 17 = 0.000_3 r 17 17 / 21 = 170 (17 * 10^1) / 21 = 8 scale 1 + 4 r 2 = 0.000_08 r 2 2 / 21 = 200 (2 * 10^2) / 21 = 9 scale 2 + 5 r 11 = 0.000_000_9 r 11
So a repeating decimal sequence of 952380 -> 243.952380952380952 After the final 2, the next digit is a 3, which means rounding down Final result is still 243.952380952380952
11. 5 / 9 = 0.555... By generating a 19th digit of 5, the result rounds to 0.555_555_555_555_555_556
12. 1.03075 / 0.25 103075 / 25 = 4123 Scale 5 - scale 2 = 3 Result is 4.123
13. 1_234_567_890_123_456.78 / 2.5 123_456_789_012_345_678 / 25 = 4_938_271_560_493_827 r 3 Scale 2 - scale 1 = 1 -> 4_938_271_560_493_827 scale 1 = 493_827_156_049_382.7 3 / 25 = 30 (3 * 10^1) / 25 = 1 scale 1 + 1 r 5 = 0.01 r 5 5 / 25 = 50 (5 * 10^1) / 25 = 2 scale 1 + 2 r 0 = 0.002 Result is 493_827_156_049_382.7 + 0.012 = 493_827_156_049_382.712
14. 1_234_567_890_123_456.78 / 0.25 123_456_789_012_345_678 / 25 = 4_938_271_560_493_827 r 3 Scale 2 - scale 2 = scale 0 -> 4_938_271_560_493_827 3 / 25 = 30 (3 * 10^1) / 25 = 1 scale 1 + 0 r 5 = 0.1 r 5 5 / 25 = 50 (5 * 10^1) / 25 = 2 scale 1 + 1 r 0 = 0.02 Result is 4_938_271_560_493_827 + 0.12 = 4_938_271_560_493_827.12
15. 1_234_567_890_123_456.78 / 0.00025 123_456_789_012_345_678 / 25 = 4_938_271_560_493_827 r 3 Scale 2 - scale 5 = -3 -> Multiply by 10^3 4_938_271_560_493_827_000 = 19 digits = overflow
16. 1 / 100_000_000_000_000_000 1 / 100_000_000_000_000_000 = 100_000_000_000_000_000 (1 * 10^17) / 100_000_000_000_000_000 = 1 scale 17 = 0.000_000_000_000_000_01
17. 1 / 200_000_000_000_000_000 1 / 200_000_000_000_000_000 = 1 * 10^18 / 200_000_000_000_000_000, 1 * 10^18 is too large to store = overflow
18. 100_000_000_000_000_000 / 0.1 = 100_000_000_000_000_000 / 1 = 100_000_000_000_000_000 Scale 0 - 1 = -1 = Multiply by 10^1 = 1 * 10^18 = overflow
func (Decimal) DivIntAdd ¶
DintIntAdd is like DivIntQuoRem, except that it returns a slice of values that add up to d. EG, 100.00 / 3 = [33.34, 33.33, 33.33]. This method just calls DivIntQuoRem and spreads the remainder across the first remainder values returned.
func (Decimal) DivIntQuoRem ¶
DivIntQuoRem divides d by unsigned integer o, and returns (quotient, remainder, error). The scale of the quotient and remainder are the same as that of d. EG, 100.00 / 3 = 33.33 remainder 0.01.
The divisor o cannot be larger than the dividend d.
Returns a division by zero error if o is zero. Returns a divisor too large error if the o > d.value.
func (Decimal) MagnitudeLessThanOne ¶
MagnitudeLessThanOne returns true if the decimal value represents a value whose mangitude < 1
func (Decimal) Mul ¶
Mul calculates d * o using one of two methods:
1. r = d * o is tried first If r = 0, then return 0 scale 0. If r / d = o, then if r > max value or < min value, we have a valid result 19 digits in length.
Round it to 18 with single divide by 10, and add 1 if remainder >= 5. Given max int64 value starts with 92, divide by 10 cannot be max value.
Otherwise, go to method 2 below.
The resulting scale rs is d scale + o scale. If rs <= 18, just return r with scale rs. Otherwise, round r (rs - 18) times. If the result is 0, return 0 scale 0, else return r scale rs.
2. If r / d != o, we have a case where d * o exceeds bounds of 64 bit integers. Split d and o into 32-bit upper/lower pairs, and perform a series of shift and adds that generate a 128-bit result.
The 128 bit result is first rounded down to 18 digits, reducing rs by up to 18. If rs = 0 and there are more than 18 digitds l The result rs must be <= 18, return as is.
func (Decimal) MustDivIntAdd ¶
MustDivIntAdd is a must version of DivIntAdd
func (Decimal) MustDivIntQuoRem ¶
MustDivIntQuoRem is a must version of DivIntQuoRem
func (*Decimal) Normalize ¶
func (d *Decimal) Normalize()
Normalize has two cases: value = 0: ensure scale = 0 scale > 0: eliminate useless trailing zeros This can help improve accuracy over successive calculations. This method is the only method that ignores the internal normalize field, to allow forcing normalization as desired.
func (Decimal) Normalized ¶
Normalized returns true if the operations return normalized values
func (Decimal) Precision ¶
Precison returns the total number of digits of a decimal, including trailing zeros. Effectively, the length of the decimal as a string, without a minus sign or decimal point.
type Range ¶
type Range[T constraint.IntegerAndFloat] struct { // contains filtered or unexported fields }
Range represents a range of values. The range may be open, half open, or closed.
func OfRange ¶
func OfRange[T constraint.IntegerAndFloat]( min T, minMode RangeMode, max T, maxMode RangeMode, initial T, ) Range[T]
OfRange constructs a range from minimum value and mode, maximum value and mode, and initial value. An initial value is required since min and max could both be open and the type could a float, so there is no sensible default initial value.
Panics if the initial value is not in the specified range.