2025-02-06 11:14:33 +08:00
|
|
|
|
package utility
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"math/rand"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/shopspring/decimal"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func StrToDecimal(data string) decimal.Decimal {
|
|
|
|
|
|
result, _ := decimal.NewFromString(data)
|
|
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DecimalCutStr 按保留的小数点位数,去掉多余的小数 非四舍五入
|
|
|
|
|
|
func DecimalCutStr(num decimal.Decimal, size int32) string {
|
|
|
|
|
|
if num.Cmp(decimal.Zero) == 0 {
|
|
|
|
|
|
return `0`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
str := num.Truncate(size)
|
|
|
|
|
|
result := str.String()
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Random 生成一个在 [start, end] 范围内的随机数,保留一位小数
|
|
|
|
|
|
// start 开始数字
|
|
|
|
|
|
// end 结束数字
|
|
|
|
|
|
// floatNum 保留小数位数
|
|
|
|
|
|
func DecimalRandom(start, end decimal.Decimal, floatNum int) decimal.Decimal {
|
|
|
|
|
|
// 创建一个本地随机数生成器
|
|
|
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
|
|
|
|
|
|
|
|
// 将 start 和 end 转换为浮点数
|
|
|
|
|
|
startFloat, _ := start.Float64()
|
|
|
|
|
|
endFloat, _ := end.Float64()
|
|
|
|
|
|
|
|
|
|
|
|
// 生成随机数
|
|
|
|
|
|
randomFloat := startFloat + r.Float64()*(endFloat-startFloat)
|
|
|
|
|
|
|
|
|
|
|
|
// 保留一位小数
|
|
|
|
|
|
randomDecimal := decimal.NewFromFloat(randomFloat).Round(int32(floatNum))
|
|
|
|
|
|
|
|
|
|
|
|
return randomDecimal
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DiscardDecimal 舍弃 decimal 类型的最后指定位数小数
|
|
|
|
|
|
// value: 输入的 decimal 值
|
|
|
|
|
|
// discardDigits: 需要舍弃的小数位数
|
|
|
|
|
|
func DiscardDecimal(value decimal.Decimal, discardDigits int32) decimal.Decimal {
|
|
|
|
|
|
// 如果 discardDigits 小于 0,直接返回原值
|
|
|
|
|
|
if discardDigits < 0 {
|
|
|
|
|
|
return value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前值的小数位数
|
|
|
|
|
|
currentPrecision := value.Exponent() * -1
|
|
|
|
|
|
|
|
|
|
|
|
// 获取整数部分
|
|
|
|
|
|
integerPart := value.Truncate(0)
|
|
|
|
|
|
|
|
|
|
|
|
// 如果小数位数超过一位且小于两位
|
|
|
|
|
|
if currentPrecision > 1 && currentPrecision < 2 {
|
|
|
|
|
|
// 如果有整数部分,截断一位小数
|
|
|
|
|
|
if !integerPart.IsZero() {
|
|
|
|
|
|
return value.Truncate(currentPrecision - 1)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 如果没有整数部分,按正常流程处理
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果小数位数只有一位
|
|
|
|
|
|
if currentPrecision == 1 {
|
|
|
|
|
|
// 如果有整数部分,返回整数部分
|
|
|
|
|
|
if !integerPart.IsZero() {
|
|
|
|
|
|
return integerPart
|
|
|
|
|
|
}
|
|
|
|
|
|
// 如果没有整数部分,保持原数据不变
|
|
|
|
|
|
return value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果小数位数超过两位,按正常流程处理
|
|
|
|
|
|
if currentPrecision > discardDigits {
|
|
|
|
|
|
precision := currentPrecision - discardDigits
|
|
|
|
|
|
return value.Truncate(precision)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return value
|
|
|
|
|
|
}
|
2025-03-11 15:51:40 +08:00
|
|
|
|
|
|
|
|
|
|
// SafeDiv 安全除法
|
|
|
|
|
|
// dividend: 被除数
|
|
|
|
|
|
// divisor: 除数
|
|
|
|
|
|
func SafeDiv(dividend, divisor decimal.Decimal) decimal.Decimal {
|
|
|
|
|
|
var result decimal.Decimal
|
|
|
|
|
|
|
|
|
|
|
|
if dividend.Cmp(decimal.Zero) != 0 && divisor.Cmp(decimal.Zero) != 0 {
|
|
|
|
|
|
result = dividend.Div(divisor)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|