zhangqian
2024-04-30 7dd6097d42d6d6f254a84ab0111bac70f0358660
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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)
}