## zhenyangze/zlib .gitee-modal { width: 500px !important; }

Create your Gitee Account
Explore and code with more than 12 million developers，Free private repositories ！：）
math.go 15.13 KB
zhenyangze authored 2022-10-04 23:27 . master: [feature] update package
package zlib

import (
"fmt"
"math"
"math/rand"
"reflect"
"strconv"
"strings"
"time"
)

// RandRange 获取指定范围内的可变随机整数数，正负都行。[a, b]
func RandRange(_min int64, _max int64) int64 {
var _rand int64
if _min >= _max {
_rand = 0
} else {
rand.Seed(time.Now().UnixNano())
_rand = rand.Int63n(_max-_min) + _min
}
return _rand
}

// RandString 生成指定长度的字符串
func RandString(_length int64) string {
var length int64
if _length >= 1 {
length = _length
} else {
length = 1
}
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
bytes := []byte(str)
var result []byte
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < int(length); i++ {
result = append(result, bytes[r.Int63n(int64(len(bytes)))])
}
return string(result)
}

// 小数点后 n 位 - 四舍五入
func RoundedFixed(val float64, n int) float64 {
shift := math.Pow(10, float64(n))
fv := 0.0000000001 + val //对浮点数产生.xxx999999999 计算不准进行处理
return math.Floor(fv*shift+.5) / shift
}

// 小数点后 n 位 - 舍去
func TruncRound(val float64, n int) float64 {
floatStr := fmt.Sprintf("%."+strconv.Itoa(n+1)+"f", val)
temp := strings.Split(floatStr, ".")
var newFloat string
if len(temp) < 2 || n >= len(temp[1]) {
newFloat = floatStr
} else {
newFloat = temp[0] + "." + temp[1][:n]
}
inst, _ := strconv.ParseFloat(newFloat, 64)
return inst
}

// AbsFloat 浮点型取绝对值.
func AbsFloat(number float64) float64 {
return math.Abs(number)
}

// AbsInt 整型取绝对值.
func AbsInt(number int64) int64 {
r := number >> 63
return (number ^ r) - r
}

// (n ^ shifted) - shifted = 5 - 0 = 5
func AbsInt8(n int8) int8 {
shifted := n >> 7
return (n ^ shifted) - shifted
}

// AbsInt16 gets absolute value of int16.
func AbsInt16(n int16) int16 {
shifted := n >> 15
return (n ^ shifted) - shifted
}

// AbsInt32 gets absolute value of int32.
func AbsInt32(n int32) int32 {
shifted := n >> 31
return (n ^ shifted) - shifted
}

// AbsInt64 gets absolute value of int64.
func AbsInt64(n int64) int64 {
shifted := n >> 63
return (n ^ shifted) - shifted
}

// Range 根据范围创建数组,包含指定的元素.
// start为起始元素值,end为末尾元素值.若start<end,返回升序的数组;若start>end,返回降序的数组.
func Range(start, end int) []int {
res := make([]int, AbsInt(int64(end-start))+1)
for i := range res {
if end > start {
res[i] = start + i
} else {
res[i] = start - i
}
}
return res
}

// NumberFormat 以千位分隔符方式格式化一个数字.
// decimal为要保留的小数位数,point为小数点显示的字符,thousand为千位分隔符显示的字符.
// 有效数值是长度(包括小数点)为17位之内的数值,最后一位会四舍五入.
func NumberFormat(number float64, decimal uint8, point, thousand string) string {
neg := false
if number < 0 {
number = -number
neg = true
}
dec := int(decimal)
// Will round off
str := fmt.Sprintf("%."+strconv.Itoa(dec)+"F", number)
prefix, suffix := "", ""
if dec > 0 {
prefix = str[:len(str)-(dec+1)]
suffix = str[len(str)-dec:]
} else {
prefix = str
}
sep := []byte(thousand)
n, l1, l2 := 0, len(prefix), len(sep)
// thousands sep num
c := (l1 - 1) / 3
tmp := make([]byte, l2*c+l1)
pos := len(tmp) - 1
for i := l1 - 1; i >= 0; i, n, pos = i-1, n+1, pos-1 {
if l2 > 0 && n > 0 && n%3 == 0 {
for j := range sep {
tmp[pos] = sep[l2-j-1]
pos--
}
}
tmp[pos] = prefix[i]
}
s := string(tmp)
if dec > 0 {
s += point + suffix
}
if neg {
s = "-" + s
}

return s
}

// FloatEqual 比较两个浮点数是否相等.decimal为小数精确位数,默认为 FLOAT_DECIMAL .
// 有效数值是长度(包括小数点)为17位之内的数值,最后一位会四舍五入.
func FloatEqual(f1 float64, f2 float64, decimal ...uint8) (res bool) {
var threshold float64
var dec uint8
if len(decimal) == 0 {
dec = FLOAT_DECIMAL
} else {
dec = decimal[0]
}

//比较精度
threshold = math.Pow10(-int(dec))
var diff float64
if f1 > f2 {
diff = f1 - f2
} else {
diff = f2 - f1
}

//diff := math.Abs(f1 - f2)
res = diff <= threshold

return
}

// RandInt64 生成一个min~max范围内的随机int64整数.
func RandInt64(min, max int64) int64 {
if min > max {
min, max = max, min
} else if min == max {
return min
}

//范围是否在边界内
mMax := int64(math.MaxInt32)
mMin := int64(math.MinInt32)
inrang := (mMin <= min && max <= mMax) || (INT64_MIN <= min && max <= 0) || (0 <= min && max <= INT64_MAX)
if !inrang {
min, max = mMin, mMax
}

r := rand.New(rand.NewSource(time.Now().UnixNano()))
return r.Int63n(max-min) + min
}

// RandInt 生成一个min~max范围内的随机int整数.
func RandInt(min, max int) int {
if min > max {
min, max = max, min
} else if min == max {
return min
}

//范围是否在边界内
mMax := int(math.MaxInt32)
mMin := int(math.MinInt32)
inrang := (mMin <= min && max <= mMax) || (INT_MIN <= min && max <= 0) || (0 <= min && max <= INT_MAX)
if !inrang {
min, max = mMin, mMax
}

r := rand.New(rand.NewSource(time.Now().UnixNano()))
return r.Intn(max-min) + min
}

// Rand RandInt的别名.
func Rand(min, max int) int {
return RandInt(min, max)
}

// RandFloat64 生成一个min~max范围内的随机float64浮点数.
func RandFloat64(min, max float64) float64 {
if min > max {
min, max = max, min
}

//范围是否在边界内
mMax := float64(math.MaxFloat32)
mMin := -mMax
inrang := (mMin <= min && max <= mMax) || (-math.MaxFloat64 <= min && max <= 0) || (0 <= min && max <= math.MaxFloat64)
if !inrang {
min, max = mMin, mMax
}

r := rand.New(rand.NewSource(time.Now().UnixNano()))
num := r.Float64()

res := min + num*(max-min)
return res
}

// Round 对浮点数(的整数)进行四舍五入.
func Round(value float64) float64 {
return math.Floor(value + 0.5)
}

// RoundPlus 对指定的小数位进行四舍五入.
// precision为小数位数.
func RoundPlus(value float64, precision uint8) float64 {
shift := math.Pow(10, float64(precision))
return Round(value*shift) / shift
}

// Floor 向下取整.
func Floor(value float64) float64 {
return math.Floor(value)
}

// Ceil 向上取整.
func Ceil(value float64) float64 {
return math.Ceil(value)
}

// MaxInt 整数序列求最大值.
func MaxInt(nums ...int) (res int) {
if len(nums) < 1 {
panic("[MaxInt] nums length is less than 1")
}

res = nums[0]
for _, v := range nums {
if v > res {
res = v
}
}

return
}

// MaxFloat64 64位浮点数序列求最大值.
func MaxFloat64(nums ...float64) (res float64) {
if len(nums) < 1 {
panic("[MaxFloat64] nums length is less than 1")
}

res = nums[0]
for _, v := range nums {
res = math.Max(res, v)
}

return
}

// Max 取出任意类型中数值类型的最大值,无数值类型则为0.
func Max(nums ...interface{}) (res float64) {
if len(nums) < 1 {
panic("[Max] nums length is less than 1")
}

var val float64
res = InterfaceToFloat(nums[0])
for _, v := range nums {
val = InterfaceToFloat(v)
res = math.Max(res, val)
}

return
}

// MinInt 整数序列求最小值.
func MinInt(nums ...int) (res int) {
if len(nums) < 1 {
panic("[MinInt] nums length is less than 1")
}
res = nums[0]
for _, v := range nums {
if v < res {
res = v
}
}

return
}

// MinFloat64 64位浮点数序列求最小值.
func MinFloat64(nums ...float64) (res float64) {
if len(nums) < 1 {
panic("[MinFloat64] nums length is less than 1")
}
res = nums[0]
for _, v := range nums {
res = math.Min(res, v)
}

return
}

// Min 取出任意类型中数值类型的最小值,无数值类型则为0.
func Min(nums ...interface{}) (res float64) {
if len(nums) < 1 {
panic("[Min] nums length is less than 1")
}

var val float64
res = InterfaceToFloat(nums[0])
for _, v := range nums {
val = InterfaceToFloat(v)
res = math.Min(res, val)
}

return
}

// Exp 计算 e 的指数.
func Exp(x float64) float64 {
return math.Exp(x)
}

// Expm1 返回 exp(x) - 1.
func Expm1(x float64) float64 {
return math.Exp(x) - 1
}

// Pow 指数表达式,求x的y次方.
func Pow(x, y float64) float64 {
return math.Pow(x, y)
}

// Log 对数表达式,求以y为底x的对数.
func Log(x, y float64) float64 {
return math.Log(x) / math.Log(y)
}

// ByteFormat 格式化文件比特大小.
// size为文件大小,decimal为要保留的小数位数,delimiter为数字和单位间的分隔符.
func ByteFormat(size float64, decimal uint8, delimiter string) string {
var arr = []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", Unknown}
var pos int = 0
var j float64 = float64(size)
for {
if size >= 1024 {
size = size / 1024
j = j / 1024
pos++
} else {
break
}
}
if pos >= len(arr) { // fixed out index bug
pos = len(arr) - 1
}

return fmt.Sprintf("%."+strconv.Itoa(int(decimal))+"f%s%s", j, delimiter, arr[pos])
}

// IsOdd 变量是否奇数.
func IsOdd(val int) bool {
return val%2 != 0
}

// IsEven 变量是否偶数.
func IsEven(val int) bool {
return val%2 == 0
}

// NumSign 返回数值的符号.值>0为1,<0为-1,其他为0.
func NumSign(value float64) (res int8) {
if value > 0 {
res = 1
} else if value < 0 {
res = -1
} else {
res = 0
}

return
}

// IsNegative 数值是否为负数.
func IsNegative(value float64) bool {
return value < 0
}

// IsPositive 数值是否为正数.
func IsPositive(value float64) bool {
return value > 0
}

// IsNonNegative 数值是否为非负数.
func IsNonNegative(value float64) bool {
return value >= 0
}

// IsNonPositive 数值是否为非正数.
func IsNonPositive(value float64) bool {
return value <= 0
}

// IsWhole 数值是否为整数.
func IsWhole(value float64) bool {
return math.Remainder(value, 1) == 0
}

// IsNatural 数值是否为自然数(包括0).
func IsNatural(value float64) bool {
return IsNonNegative(value) && IsWhole(value)
}

// InRangeInt 数值是否在2个整数范围内.
func InRangeInt(value, left, right int) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}

// InRangeFloat64 数值是否在2个64位浮点数范围内.
func InRangeFloat64(value, left, right float64) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}

// InRangeFloat32 数值是否在2个32位浮点数范围内.
func InRangeFloat32(value, left, right float32) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}

// InRange 数值是否在某个范围内,将自动转换类型再比较.
func InRange(value interface{}, left interface{}, right interface{}) bool {
reflectValue := reflect.TypeOf(value).Kind()
reflectLeft := reflect.TypeOf(left).Kind()
reflectRight := reflect.TypeOf(right).Kind()

if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int {
return InRangeInt(value.(int), left.(int), right.(int))
} else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 {
return InRangeFloat32(value.(float32), left.(float32), right.(float32))
} else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 {
return InRangeFloat64(value.(float64), left.(float64), right.(float64))
} else if IsInt(value) && IsInt(left) && IsInt(right) {
return InRangeInt(InterfaceToInt(value), InterfaceToInt(left), InterfaceToInt(right))
} else if IsNumeric(value) && IsNumeric(left) && IsNumeric(right) {
return InRangeFloat64(InterfaceToFloat(value), InterfaceToFloat(left), InterfaceToFloat(right))
}

return false
}

// SumInt 整数求和.
func SumInt(nums ...int) int {
var sum int
for _, v := range nums {
sum += v
}
return sum
}

// SumFloat64 浮点数求和.
func SumFloat64(nums ...float64) float64 {
var sum float64
for _, v := range nums {
sum += v
}
return sum
}

// Sum 对任意类型序列中的数值类型求和,忽略非数值的.
func Sum(nums ...interface{}) (res float64) {
var val float64
for _, v := range nums {
val = InterfaceToFloat(v)
res += val
}

return
}

// AverageInt 对整数序列求平均值.
func AverageInt(nums ...int) (res float64) {
length := len(nums)
if length == 0 {
return
} else if length == 1 {
res = float64(nums[0])
} else {
total := SumInt(nums...)
res = float64(total) / float64(length)
}

return
}

// AverageFloat64 对浮点数序列求平均值.
func AverageFloat64(nums ...float64) (res float64) {
length := len(nums)
if length == 0 {
return
} else if length == 1 {
res = nums[0]
} else {
total := SumFloat64(nums...)
res = total / float64(length)
}

return
}

// Average 对任意类型序列中的数值类型求平均值,忽略非数值的.
func Average(nums ...interface{}) (res float64) {
length := len(nums)
if length == 0 {
return
} else if length == 1 {
res = InterfaceToFloat(nums[0])
} else {
var count int
var val, total float64
for _, v := range nums {
val = InterfaceToFloat(v)
count++
total += val
}

res = total / float64(count)
}

return
}

// Percent 返回百分比((val/total) *100).
func Percent(val, total interface{}) float64 {
t := InterfaceToFloat(total)
if t == 0 {
return float64(0)
}

v := InterfaceToFloat(val)

return (v / t) * 100
}

// IsNan 是否为“非数值”.注意,这里复数也算“非数值”.
func IsNan(val interface{}) bool {
if IsFloat(val) {
return math.IsNaN(InterfaceToFloat(val))
}

return !IsNumeric(val)
}

// IsNaturalRange 是否连续的自然数数组/切片,如[0,1,2,3...],其中不能有间断.
// strict为是否严格检查元素的顺序.
func IsNaturalRange(arr []int, strict bool) (res bool) {
n := len(arr)
if n == 0 {
return
}

orig := Range(0, n-1)
ctyp := COMPARE_ONLY_VALUE

if strict {
ctyp = COMPARE_BOTH_KEYVALUE
}

diff := ArrayDiff(orig, arr, ctyp)

res = len(diff) == 0
return
}

// GeoDistance 获取地理距离/米.
// 参数分别为两点的经度和纬度:lat:-90~90,lng:-180~180.
func GeoDistance(lng1, lat1, lng2, lat2 float64) float64 {
//地球半径
radius := 6371000.0
rad := math.Pi / 180.0

lng1 = lng1 * rad
lat1 = lat1 * rad
lng2 = lng2 * rad
lat2 = lat2 * rad
theta := lng2 - lng1

dist := math.Acos(math.Sin(lat1)*math.Sin(lat2) + math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta))
return dist * radius
}

// NearLogarithm 求以 base 为底 num 的对数临近值.
// num为自然数,base为正整数,left是否向左取整.
func NearLogarithm(num, base int, left bool) int {
if num < 0 {
panic("[nearLogarithm] num must be non-negative")
} else if base <= 0 {
panic("[nearLogarithm] base must be a positive integer")
}

res := Log(float64(num), float64(base))
if left {
return int(Floor(res))
}

return int(Ceil(res))
}

// SplitNaturalNum 将自然数 num 按底数 base 进行拆解.
func SplitNaturalNum(num, base int) []int {
var res []int

if !IsNatural(InterfaceToFloat(num)) {
panic("[splitNaturalNum] num must be a natural number")
} else if base <= 0 {
panic("[splitNaturalNum] base must be a positive integer")
}

var n, child int
for num > base {
n = NearLogarithm(num, base, true)
child = int(math.Pow(float64(base), float64(n)))
num -= child
res = append(res, child)
}

if (num > 0) || (num == 0 && len(res) == 0) {
res = append(res, num)
}

return res
}


1
https://gitee.com/zhenyangze/zlib.git
git@gitee.com:zhenyangze/zlib.git
zhenyangze
zlib
zlib
v1.0.2