mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-10 15:52:27 +08:00
feat: add mathutil package
This commit is contained in:
92
mathutil/mathutil.go
Normal file
92
mathutil/mathutil.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package mathutil implements some functions for math calculation.
|
||||||
|
package mathutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Exponent calculate x^n
|
||||||
|
func Exponent(x, n int64) int64 {
|
||||||
|
if n == 0 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
t := Exponent(x, n/2)
|
||||||
|
|
||||||
|
if n%2 == 1 {
|
||||||
|
return t * t * x
|
||||||
|
}
|
||||||
|
|
||||||
|
return t * t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fibonacci calculate fibonacci number before n
|
||||||
|
func Fibonacci(first, second, n int) int {
|
||||||
|
if n <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if n < 3 {
|
||||||
|
return 1
|
||||||
|
} else if n == 3 {
|
||||||
|
return first + second
|
||||||
|
} else {
|
||||||
|
return Fibonacci(second, first+second, n-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Factorial calculate x!
|
||||||
|
func Factorial(x uint) uint {
|
||||||
|
var f uint = 1
|
||||||
|
for ; x > 1; x-- {
|
||||||
|
f *= x
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Percent calculate the percentage of val to total
|
||||||
|
func Percent(val, total float64, n int) float64 {
|
||||||
|
if total == 0 {
|
||||||
|
return float64(0)
|
||||||
|
}
|
||||||
|
tmp := val / total * 100
|
||||||
|
res := RoundToFloat(tmp, n)
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundToString round up to n decimal places
|
||||||
|
func RoundToString(x float64, n int) string {
|
||||||
|
tmp := math.Pow(10.0, float64(n))
|
||||||
|
x *= tmp
|
||||||
|
x = math.Round(x)
|
||||||
|
res := strconv.FormatFloat(x/tmp, 'f', n, 64)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundToFloat round up to n decimal places
|
||||||
|
func RoundToFloat(x float64, n int) float64 {
|
||||||
|
tmp := math.Pow(10.0, float64(n))
|
||||||
|
x *= tmp
|
||||||
|
x = math.Round(x)
|
||||||
|
return x / tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
// TruncRound round off n decimal places
|
||||||
|
func TruncRound(x float64, n int) float64 {
|
||||||
|
floatStr := fmt.Sprintf("%."+strconv.Itoa(n+1)+"f", x)
|
||||||
|
temp := strings.Split(floatStr, ".")
|
||||||
|
var newFloat string
|
||||||
|
if len(temp) < 2 || n >= len(temp[1]) {
|
||||||
|
newFloat = floatStr
|
||||||
|
} else {
|
||||||
|
newFloat = temp[0] + "." + temp[1][:n]
|
||||||
|
}
|
||||||
|
res, _ := strconv.ParseFloat(newFloat, 64)
|
||||||
|
return res
|
||||||
|
}
|
||||||
61
mathutil/mathutil_test.go
Normal file
61
mathutil/mathutil_test.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package mathutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExponent(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestExponent")
|
||||||
|
|
||||||
|
assert.Equal(int64(1), Exponent(10, 0))
|
||||||
|
assert.Equal(int64(10), Exponent(10, 1))
|
||||||
|
assert.Equal(int64(100), Exponent(10, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFibonacci(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestFibonacci")
|
||||||
|
|
||||||
|
assert.Equal(0, Fibonacci(1, 1, 0))
|
||||||
|
assert.Equal(1, Fibonacci(1, 1, 1))
|
||||||
|
assert.Equal(1, Fibonacci(1, 1, 2))
|
||||||
|
assert.Equal(5, Fibonacci(1, 1, 5))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFactorial(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestFactorial")
|
||||||
|
|
||||||
|
assert.Equal(uint(1), Factorial(0))
|
||||||
|
assert.Equal(uint(1), Factorial(1))
|
||||||
|
assert.Equal(uint(2), Factorial(2))
|
||||||
|
assert.Equal(uint(6), Factorial(3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPercent(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestPercent")
|
||||||
|
|
||||||
|
assert.Equal(float64(50), Percent(1, 2, 2))
|
||||||
|
assert.Equal(float64(33.33), Percent(0.1, 0.3, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoundToFloat(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestRoundToFloat")
|
||||||
|
|
||||||
|
assert.Equal(RoundToFloat(0, 0), float64(0))
|
||||||
|
assert.Equal(RoundToFloat(0, 1), float64(0))
|
||||||
|
assert.Equal(RoundToFloat(0.124, 2), float64(0.12))
|
||||||
|
assert.Equal(RoundToFloat(0.125, 2), float64(0.13))
|
||||||
|
assert.Equal(RoundToFloat(0.125, 3), float64(0.125))
|
||||||
|
assert.Equal(RoundToFloat(33.33333, 2), float64(33.33))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoundToString(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestRoundToString")
|
||||||
|
|
||||||
|
assert.Equal(RoundToString(0, 0), "0")
|
||||||
|
assert.Equal(RoundToString(0, 1), "0.0")
|
||||||
|
assert.Equal(RoundToString(0.124, 2), "0.12")
|
||||||
|
assert.Equal(RoundToString(0.125, 2), "0.13")
|
||||||
|
assert.Equal(RoundToString(0.125, 3), "0.125")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user