package utils import ( "github.com/shopspring/decimal" "sort" ) // Average 取平均值 func Average(numbers []decimal.Decimal) decimal.Decimal { if len(numbers) == 0 { return decimal.Decimal{} } if len(numbers) == 1 { return numbers[0] } var sum decimal.Decimal for _, d := range numbers { sum = sum.Add(d) } return sum.Div(decimal.NewFromInt(int64(len(numbers)))) } // Deviation 偏差 func Deviation(numbers []decimal.Decimal) decimal.Decimal { if len(numbers) == 0 || len(numbers) == 1 { return decimal.Decimal{} } avgNum := Average(numbers) var diffSquaredSum decimal.Decimal for _, n := range numbers { diff := n.Sub(avgNum) diffSquaredSum = diffSquaredSum.Add(diff.Mul(diff)) } return diffSquaredSum.Div(decimal.NewFromInt(int64(len(numbers)))) } // TotalDeviation 总差 func TotalDeviation(numbers []decimal.Decimal, average decimal.Decimal) decimal.Decimal { if len(numbers) < 2 { return decimal.Zero } n := len(numbers) ratio := decimal.NewFromFloat(0.02) length := decimal.NewFromInt(int64(n)).Mul(ratio).Ceil().IntPart() if length >= int64(n) { return decimal.Zero } sort.Slice(numbers, func(i, j int) bool { return numbers[i].LessThan(numbers[j]) }) minPart := numbers[:length-1] maxPart := numbers[length:] minAverage := Average(minPart) maxAverage := Average(maxPart) minDiff := minAverage.Sub(average).Abs() maxDiff := maxAverage.Sub(average).Abs() return decimal.Max(minDiff, maxDiff) }