diff --git a/cryptor/rsa_private_example.pem b/cryptor/rsa_private_example.pem index 91b1a19..cfc0457 100644 --- a/cryptor/rsa_private_example.pem +++ b/cryptor/rsa_private_example.pem @@ -1,51 +1,51 @@ -----BEGIN rsa private key----- -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 -----END rsa private key----- diff --git a/cryptor/rsa_public_example.pem b/cryptor/rsa_public_example.pem index 1c524d3..79deb44 100644 --- a/cryptor/rsa_public_example.pem +++ b/cryptor/rsa_public_example.pem @@ -1,14 +1,14 @@ -----BEGIN rsa public key----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3bRSY5GD7uJB3jvwqa9Z -ZFpN3uLIGbbPA+yiyf6tJZp3K3rmkVFfEcWqtK1EfHvd9G4rqLYJ9ZcohDZgD/Ww -mqJtaaWh2/7feMPaitp50bYVilpPhaxULx+MIjQn3XXowYvr4fX7N052t4IC95tA -anPEEwZRQJOVMtibAxwI/ofUOCpTPtuK3AoErDxS18JPgjQ34yY4Jsch0de53+Sj -Tk+bJpLUlnY4brm+A23FhwTlE5njrKA+Texrg52KJ8aPhLuVQBcZP1SJsxv2PZru -uD+0xfLDRrZ7BOTpun+1FBhdlxBefIfBQbBBfy7STw+ignTaO+IRIHhcqKZ+12Na -+4GAusmpSiB3LATy82h0nB0PX3hSOLYmFI61px4l/yM50E4brF1NFtd/BpoozZaj -gxjJaznuZXFQ1YSG0JjCeszqdzU+6dexGTr+4Lr87NfLekmUX1nZYy/E5lST65lG -lI4hX1nR5+nVN9ALRYByNz6oJd0IfF4dhoNlGPc1VksskeY8rPZwXITbSifAN7zv -EiwKreFV3t0BLKsvWRu9GdpWy+d2AmelXkNm+QaH2mPM17euMoNZVyzizrZaJkh/ -aHO/UgY1/y7sXFl4akC9hk9ILONCUn6FVI4BXMXb5kZgwDk5tWE5A159LtC579yG -cnxyc9Y9NNFOGrqFqPiu6QUCAwEAAQ== +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAymvyNgI0T1P/DnFA2Fom +Mrx4SzBf9p4VJ70AyYmbdeGhtzh+u6zNoDQ2UMmDzcCbtv9JW7PX80O8xy/O006g +eNPfW74T5ryH2GEj3Y+eOtIzYI6gQy74JXqiqEztE6BkvesYHC+Yo8IIrawBBYHg +GvluAudTZPqnkcqnUd8ngfhahCQrMi+sKqiqOWC/D0FVSclfugWw5/EBxJJSBSPY +umLJelbk3PqXtVm46mvGnlQlfHGppYQ5Nj6zKilCgoJoAHURp4dAaOwAhVOtc31M +0WPre/9th4TodZu1GeqFt5HqmMeP5+p2GDNDSxDNP3lgCgSqwRzy4pYaE5e70azn +Os5iaclAAlrLN3aSK6lDT+BGQbQrQgM47x3flMfszqNeuaBwdiNyzEodhT8eiYl8 +m08B1sVI811q7pG8WUVZjIYs2BzVjK/VDnvbEyayX+RGCAXr5M/bfDM1YRfVS9TW +xspQNB3pyxgLX//LJIATbutUVKcrjxjoS7GdEocSruTOm/J+ZMTm0EqhsbRHVm+7 +GcsSLaiSACEq+ONQJsN1x1o2GGVEi3pEZnDITSsokdcyrBj1A9a5Hx4tSiMbg88g +S4MPOALzBTmEVneQC+U5HTG/erUpZk6/AhT9Flk3HQTNIdzz8a2Clfeh4GU1JoKB +4u++XPt4M5h75OWnd5r9HYUCAwEAAQ== -----END rsa public key----- diff --git a/docs/api/packages/mathutil.md b/docs/api/packages/mathutil.md index 8ea258a..0f07daa 100644 --- a/docs/api/packages/mathutil.md +++ b/docs/api/packages/mathutil.md @@ -52,6 +52,8 @@ import ( - [Sum](#Sum) - [Abs](#Abs) - [Div](#Div) +- [Variance](#Variance) +- [StdDev](#StdDev)
@@ -64,7 +66,7 @@ import ( 函数签名: ```go -func Average[T constraints.Integer | constraints.Float](numbers ...T) T +func Average[T constraints.Integer | constraints.Float](numbers ...T) float64 ``` 示例:[运行](https://go.dev/play/p/HFd70x4DrMj) @@ -87,7 +89,7 @@ func main() { fmt.Println(result2) // Output: - // 1 + // 1.5 // 1.3 } ``` @@ -1166,7 +1168,7 @@ func main() { ### Variance -计算方差
+计算方差。
函数签名: @@ -1195,4 +1197,37 @@ func main() { // 2 // 2.42 } +``` + +### StdDev + +计算标准差。
+ +函数签名: + +```go +func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +示例:[Run](todo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(mathutil.StdDev([]int{1, 2, 3, 4, 5}), 2) + result2 := mathutil.TruncRound(mathutil.StdDev([]float64{1.1, 2.2, 3.3, 4.4, 5.5}), 2) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.41 + // 1.55 +} ``` \ No newline at end of file diff --git a/docs/en/api/packages/mathutil.md b/docs/en/api/packages/mathutil.md index 0133c79..6d1ac0f 100644 --- a/docs/en/api/packages/mathutil.md +++ b/docs/en/api/packages/mathutil.md @@ -53,6 +53,7 @@ import ( - [Abs](#Abs) - [Div](#Div) - [Variance](#Variance) +- [StdDev](#StdDev) @@ -65,7 +66,7 @@ import ( Signature: ```go -func Average[T constraints.Integer | constraints.Float](numbers ...T) T +func Average[T constraints.Integer | constraints.Float](numbers ...T) float64 ``` Example:[Run](https://go.dev/play/p/Vv7LBwER-pz) @@ -88,7 +89,7 @@ func main() { fmt.Println(result2) // Output: - // 1 + // 1.5 // 1.3 } ``` @@ -1186,13 +1187,46 @@ import ( func main() { result1 := mathutil.Variance([]int{1, 2, 3, 4, 5}) - result2 := mathutil.Variance([]float64{1.1, 2.2, 3.3, 4.4, 5.5}) + result2 := mathutil.Variance([]float64{1.1, 2.2, 3.3, 4.4, 5.5}) - fmt.Println(result1) - fmt.Println(result2) + fmt.Println(result1) + fmt.Println(result2) - // Output: - // 2 - // 2.42 + // Output: + // 2 + // 2.42 +} +``` + +### StdDev + +Returns the standard deviation of numbers.
+ +Signature: + +```go +func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 +``` + +Example:[Run](todo) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/mathutil" +) + +func main() { + result1 := mathutil.TruncRound(mathutil.StdDev([]int{1, 2, 3, 4, 5}), 2) + result2 := mathutil.TruncRound(mathutil.StdDev([]float64{1.1, 2.2, 3.3, 4.4, 5.5}), 2) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.41 + // 1.55 } ``` \ No newline at end of file diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index 742f466..0f4c2d7 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -224,14 +224,12 @@ func Sum[T constraints.Integer | constraints.Float](numbers ...T) T { // Average return average value of numbers. // Play: https://go.dev/play/p/Vv7LBwER-pz -func Average[T constraints.Integer | constraints.Float](numbers ...T) T { - var sum T - n := T(len(numbers)) - - for _, v := range numbers { - sum += v +func Average[T constraints.Integer | constraints.Float](numbers ...T) float64 { + var sum float64 + for _, num := range numbers { + sum += float64(num) } - return sum / n + return sum / float64(len(numbers)) } // Range creates a slice of numbers from start with specified count, element step is 1. @@ -405,11 +403,17 @@ func Variance[T constraints.Float | constraints.Integer](numbers []T) float64 { } avg := Average(numbers...) - var sum T + var sum float64 for _, v := range numbers { - sum += (v - avg) * (v - avg) + sum += (float64(v) - avg) * (float64(v) - avg) } - return float64(sum) / float64(n) + return sum / float64(n) +} + +// StdDev returns the standard deviation of numbers. +// Play: todo +func StdDev[T constraints.Float | constraints.Integer](numbers []T) float64 { + return math.Sqrt(Variance(numbers)) } diff --git a/mathutil/mathutil_exmaple_test.go b/mathutil/mathutil_exmaple_test.go index dd792f5..1408aab 100644 --- a/mathutil/mathutil_exmaple_test.go +++ b/mathutil/mathutil_exmaple_test.go @@ -178,7 +178,7 @@ func ExampleAverage() { fmt.Println(result2) // Output: - // 1 + // 1.5 // 1.3 } @@ -490,3 +490,15 @@ func ExampleVariance() { // 2 // 2.42 } + +func ExampleStdDev() { + result1 := TruncRound(StdDev([]int{1, 2, 3, 4, 5}), 2) + result2 := TruncRound(StdDev([]float64{1.1, 2.2, 3.3, 4.4, 5.5}), 2) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1.41 + // 1.55 +} diff --git a/mathutil/mathutil_test.go b/mathutil/mathutil_test.go index 36adf82..b79fb24 100644 --- a/mathutil/mathutil_test.go +++ b/mathutil/mathutil_test.go @@ -143,11 +143,22 @@ func TestAverage(t *testing.T) { assert := internal.NewAssert(t, "TestAverage") - assert.Equal(0, Average(0, 0)) - assert.Equal(1, Average(1, 1)) + tests := []struct { + numbers []int + expected float64 + }{ + {[]int{0}, 0}, + {[]int{1, 1, 1}, 1}, + {[]int{1, 2, 3, 4}, 2.5}, + {[]int{1, 2, 3, 4, 5}, 3}, + } - avg := Average(1.2, 1.4) - assert.Equal(1.3, RoundToFloat(avg, 1)) + for _, tt := range tests { + assert.Equal(tt.expected, Average(tt.numbers...)) + } + + avg := Average(1.1, 1.2, 1.3, 1.4) + assert.Equal(1.25, avg) } func TestSum(t *testing.T) { @@ -425,7 +436,7 @@ func TestVariance(t *testing.T) { }{ {[]int{0}, 0}, {[]int{1, 1, 1}, 0}, - {[]int{1, 2, 3, 4}, 1.5}, + {[]int{1, 2, 3, 4}, 1.25}, {[]int{1, 2, 3, 4, 5}, 2.0}, } @@ -446,3 +457,37 @@ func TestVariance(t *testing.T) { assert.Equal(tt.expected, TruncRound(Variance(tt.numbers), 2)) } } + +func TestStdDev(t *testing.T) { + + t.Parallel() + + assert := internal.NewAssert(t, "TestStdDev") + + testIntNumbers := []struct { + numbers []int + expected float64 + }{ + {[]int{0}, 0}, + {[]int{1, 1, 1}, 0}, + {[]int{1, 2, 3, 4}, 1.118}, + {[]int{1, 2, 3, 4, 5}, 1.414}, + } + + for _, tt := range testIntNumbers { + assert.Equal(tt.expected, TruncRound(StdDev(tt.numbers), 3)) + } + + testFloatNumbers := []struct { + numbers []float64 + expected float64 + }{ + {[]float64{0}, 0}, + {[]float64{1, 1, 1}, 0}, + {[]float64{1.1, 2.2, 3.3, 4.4}, 1.229}, + } + + for _, tt := range testFloatNumbers { + assert.Equal(tt.expected, TruncRound(StdDev(tt.numbers), 3)) + } +}