241 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
	
		
			6 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
 | ||
| 
 | ||
| // ToBase convertit n selon la base donnée.
 | ||
| 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
 | ||
| }
 | ||
| 
 | ||
| // ToInteger convertit n en entier.
 | ||
| func ToInteger[N integer](n Number, base ...N) Number { return toType(n, Integer, base...) }
 | ||
| 
 | ||
| // ToDecimal convertit n en décimal.
 | ||
| func ToDecimal[N integer](n Number, base ...N) Number { return toType(n, Decimal, base...) }
 | ||
| 
 | ||
| // ToFraction convertit n en fraction.
 | ||
| func ToFraction[N integer](n Number, base ...N) Number { return toType(n, Fraction, base...) }
 | ||
| 
 | ||
| // ToScientific convertit n en nombre scientifique.
 | ||
| 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 IntOf(n.Len()) }
 | ||
| func Sqrt(n Number) Number   { return n.Sqrt() }
 | ||
| func Square(n Number) Number { return n.Square() }
 | ||
| 
 | ||
| // Fonctions de type f(n, n) → n
 | ||
| func Cmp(n1, n2 Number) Number   { return IntOf(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 IntOf(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
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // Max retourne le nombre le plus grand de la liste.
 | ||
| func Max(numbers ...Number) (n Number) {
 | ||
| 	return Reduce(func(n1, n2 Number) Number {
 | ||
| 		if n2.Gt(n1) {
 | ||
| 			return n2
 | ||
| 		}
 | ||
| 		return n1
 | ||
| 	})(numbers...)
 | ||
| }
 | ||
| 
 | ||
| // Min retourne le nombre le plus petit de la liste.
 | ||
| func Min(numbers ...Number) (n Number) {
 | ||
| 	return Reduce(func(n1, n2 Number) Number {
 | ||
| 		if n2.Lt(n1) {
 | ||
| 			return n2
 | ||
| 		}
 | ||
| 		return n1
 | ||
| 	})(numbers...)
 | ||
| }
 | ||
| 
 | ||
| // Sum retourne la somme des nombres.
 | ||
| func Sum(numbers ...Number) (n Number) { return Reduce(Add)(numbers...) }
 | ||
| 
 | ||
| // Mean retourne la moyenne des nombres.
 | ||
| func Mean(numbers ...Number) (n Number) {
 | ||
| 	l := len(numbers)
 | ||
| 	if l == 0 {
 | ||
| 		return Nan()
 | ||
| 	}
 | ||
| 
 | ||
| 	return Sum(numbers...).Div(IntOf(l))
 | ||
| }
 | ||
| 
 | ||
| // Median retourne la médiane des nombres.
 | ||
| func Median(numbers ...Number) Number {
 | ||
| 	l := len(numbers)
 | ||
| 	if l == 0 {
 | ||
| 		return Nan()
 | ||
| 	}
 | ||
| 
 | ||
| 	numbers = Sort(numbers...)
 | ||
| 	return numbers[l>>1]
 | ||
| }
 | ||
| 
 | ||
| // Mode retourne retourne le mode des nombres (ie. le nombre le plus fréquent).
 | ||
| func Mode(numbers ...Number) Number {
 | ||
| 	l := len(numbers)
 | ||
| 	if l == 0 {
 | ||
| 		return Nan()
 | ||
| 	}
 | ||
| 
 | ||
| 	m := make(map[Number]int)
 | ||
| loop:
 | ||
| 	for _, n := range numbers {
 | ||
| 		for k := range m {
 | ||
| 			if k.Eq(n) {
 | ||
| 				m[k]++
 | ||
| 				continue loop
 | ||
| 			}
 | ||
| 		}
 | ||
| 		m[n] = 1
 | ||
| 	}
 | ||
| 
 | ||
| 	i := 0
 | ||
| 	var n Number
 | ||
| 	for k, j := range m {
 | ||
| 		if j > i {
 | ||
| 			n, i = k, j
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	return n
 | ||
| }
 | ||
| 
 | ||
| // Variance retourne la variance des nombres.
 | ||
| func Variance(numbers ...Number) Number {
 | ||
| 	m := Mean(numbers...)
 | ||
| 	if m.IsNan() {
 | ||
| 		return m
 | ||
| 	}
 | ||
| 
 | ||
| 	numbers = Map(func(n Number) Number {
 | ||
| 		return n.Sub(m).Square()
 | ||
| 	})(numbers...)
 | ||
| 
 | ||
| 	return Mean(numbers...)
 | ||
| }
 | ||
| 
 | ||
| // StdDeviation retourne l’écart-type des nombres.
 | ||
| func StdDeviation(numbers ...Number) Number { return Variance(numbers...).Sqrt() }
 | ||
| 
 | ||
| // Round arrondit le n selon la précision et la base données.
 | ||
| func Round(n Number, precision uint64, base ...uint) Number {
 | ||
| 	if !n.IsDefined() || n.Type() == Integer {
 | ||
| 		return n
 | ||
| 	}
 | ||
| 
 | ||
| 	b := n.Base()
 | ||
| 	if len(base) > 0 {
 | ||
| 		b = formatBase(base...)
 | ||
| 	}
 | ||
| 
 | ||
| 	p := pow(b, precision)
 | ||
| 	num, denom := n.Num().Mul(p), n.Denom()
 | ||
| 
 | ||
| 	return num.Quo(denom).Div(p).ToType(n.Type())
 | ||
| }
 | ||
| 
 | ||
| // Reverse inverse l’ordre de la liste des nombres.
 | ||
| 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
 | ||
| }
 | ||
| 
 | ||
| // Sort trie les nombres par ordre croissant.
 | ||
| func Sort(numbers ...Number) []Number {
 | ||
| 	sort.Slice(numbers, func(i, j int) bool {
 | ||
| 		return numbers[i].Lt(numbers[j])
 | ||
| 	})
 | ||
| 
 | ||
| 	return numbers
 | ||
| }
 | ||
| 
 | ||
| // SortDesc trie les nombres par ordre décroissant.
 | ||
| func SortDesc(numbers ...Number) []Number {
 | ||
| 	sort.Slice(numbers, func(i, j int) bool {
 | ||
| 		return numbers[i].Gt(numbers[j])
 | ||
| 	})
 | ||
| 
 | ||
| 	return numbers
 | ||
| }
 | 
