180 lines
4.3 KiB
Go
180 lines
4.3 KiB
Go
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
|
|
}
|