gob/number/operations.go

180 lines
4.3 KiB
Go
Raw Normal View History

2024-02-17 18:13:24 +00:00
package number
import (
"sort"
)
type Op1Func func(Number) Number
type Op2Func func(Number, Number) Number
type Op1To2Func func(Number) (Number, Number)
type Op2To2Func func(Number, Number) (Number, Number)
type ReduceFunc func(...Number) Number
type MapFunc func(...Number) []Number
func ToBase[N integer](n Number, base N) Number {
return n.ToBase(formatBase(base))
}
func toType[N integer](n Number, t NumberType, base ...N) Number {
n = n.ToType(t)
if len(base) > 0 {
n = ToBase(n, base[0])
}
return n
}
func ToInteger[N integer](n Number, base ...N) Number {
return toType(n, Integer, base...)
}
func ToDecimal[N integer](n Number, base ...N) Number {
return toType(n, Decimal, base...)
}
func ToFraction[N integer](n Number, base ...N) Number {
return toType(n, Fraction, base...)
}
func ToScientific[N integer](n Number, base ...N) Number {
return toType(n, Scientific, base...)
}
// Fonctions de type f(n) → n
func Neg(n Number) Number { return n.Neg() }
func Abs(n Number) Number { return n.Abs() }
func Num(n Number) Number { return n.Num() }
func Denom(n Number) Number { return n.Denom() }
func Inc(n Number) Number { return n.Inc() }
func Dec(n Number) Number { return n.Dec() }
func Inv(n Number) Number { return n.Inv() }
func Fact(n Number) Number { return n.Fact() }
func Len(n Number) Number { return Int(n.Len()) }
func Sqrt(n Number) Number { return n.Sqrt() }
// Fonctions de type f(n, n) → n
func Cmp(n1, n2 Number) Number { return Int(n1.Cmp(n2)) }
func Eq(n1, n2 Number) Number { return ParseBool(n1.Eq(n2)) }
func Ne(n1, n2 Number) Number { return ParseBool(n1.Ne(n2)) }
func Gt(n1, n2 Number) Number { return ParseBool(n1.Gt(n2)) }
func Lt(n1, n2 Number) Number { return ParseBool(n1.Lt(n2)) }
func Ge(n1, n2 Number) Number { return ParseBool(n1.Ge(n2)) }
func Le(n1, n2 Number) Number { return ParseBool(n1.Le(n2)) }
func Add(n1, n2 Number) Number { return n1.Add(n2) }
func Sub(n1, n2 Number) Number { return n1.Sub(n2) }
func Mul(n1, n2 Number) Number { return n1.Mul(n2) }
func Div(n1, n2 Number) Number { return n1.Div(n2) }
func Quo(n1, n2 Number) Number { return n1.Quo(n2) }
func Rem(n1, n2 Number) Number { return n1.Rem(n2) }
func Lsh(n1, n2 Number) Number { return n1.Lsh(n2) }
func Rsh(n1, n2 Number) Number { return n1.Rsh(n2) }
func Bit(n1, n2 Number) Number { return Int(n1.Bit(n2)) }
func Pow(n1, n2 Number) Number { return n1.Pow(n2) }
func Sqrtn(n1, n2 Number) Number { return n1.Sqrtn(n2) }
// Fonctions de type f(n) → (n, n)
func NumDenom(n Number) (Number, Number) { return n.NumDenom() }
// Fonctions de type f(n, n) → (n, n)
func QuoRem(n1, n2 Number) (Number, Number) { return n1.QuoRem(n2) }
// Autre
func Map(callback Op1Func) MapFunc {
return func(numbers ...Number) []Number {
out := make([]Number, len(numbers))
for i, n := range numbers {
out[i] = callback(n)
}
return out
}
}
func Reduce(callback Op2Func) ReduceFunc {
return func(numbers ...Number) Number {
var acc Number
for i, n := range numbers {
if i == 0 {
acc = n
} else {
acc = callback(acc, n)
}
}
return acc
}
}
func Max(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Gt(n1) {
return n2
}
return n1
})(numbers...)
}
func Min(numbers ...Number) (n Number) {
return Reduce(func(n1, n2 Number) Number {
if n2.Lt(n1) {
return n2
}
return n1
})(numbers...)
}
func Sum(numbers ...Number) (n Number) {
return Reduce(Add)(numbers...)
}
func Mean(numbers ...Number) (n Number) {
l := len(numbers)
if l == 0 {
return Nan()
}
return Sum(numbers...).Div(Int(l))
}
func Round(n Number, precision uint64, base ...uint) Number {
if !n.IsDefined() || n.Type() == Integer {
return n
}
p := Number{
base: n.Base(),
tpe: n.Type(),
atom: pow(formatBase(base...), precision),
}
p.format()
num, denom := n.Num().Mul(p), n.Denom()
return num.Quo(denom).Div(p)
}
func Reverse(numbers ...Number) []Number {
l := len(numbers)
for i := 0; i < l>>1; i++ {
j := l - 1 - i
numbers[i], numbers[j] = numbers[j], numbers[i]
}
return numbers
}
func Sort(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Lt(numbers[j])
})
return numbers
}
func SortDesc(numbers ...Number) []Number {
sort.Slice(numbers, func(i, j int) bool {
return numbers[i].Gt(numbers[j])
})
return numbers
}