package utils import ( "fmt" "github.com/shopspring/decimal" "golang.org/x/text/language" "golang.org/x/text/message" "strconv" "strings" ) // FormatDecimalToString decimal.Decimal func FormatDecimalToString(d decimal.Decimal) string { if d.GreaterThan(decimal.NewFromFloat(100000)) { return decimalFmtWithText0(d) } if d.GreaterThan(decimal.NewFromFloat(1000)) { return decimalFmtWithText2(d) } if d.GreaterThan(decimal.NewFromFloat(0.01)) { return d.Truncate(4).String() } return lessZeroFormat(d) } // lessZeroFormat 0.0000090235格式化为 "0.{n}1234" 形式 func lessZeroFormat(d decimal.Decimal) string { // 转为科学计数法字符串(例如 "9.0235E-6") sciNotation := customScientific(d, 4) // 分割科学计数法的基数和指数 parts := strings.Split(sciNotation, "E") if len(parts) != 2 { return d.String() // 如果不是科学计数法,直接返回原值 } // 基数部分(如 "9.0235") base := parts[0] // 指数部分(如 "-6") expStr := parts[1] // 解析指数值 exp, err := strconv.Atoi(expStr) if err != nil { return d.String() } // 计算前导零的数量(例如 0.000009 → 5个前导零) leadingZeros := -exp - 1 // 提取有效数字(去掉小数点,取前4位) digits := strings.Replace(base, ".", "", 1) if len(digits) > 4 { digits = digits[:4] // 只保留4位有效数字 } // 构造最终格式 "0.{n}xxxx" return fmt.Sprintf("0.{%d}%s", leadingZeros, digits) } func customScientific(d decimal.Decimal, precision int) string { // 获取绝对值 abs := d.Abs() // 处理零值 if abs.Equal(decimal.Zero) { return "0E+0" } // 计算指数 exp := int32(0) ten := decimal.NewFromInt(10) for abs.LessThan(decimal.NewFromInt(1)) && !abs.Equal(decimal.Zero) { abs = abs.Mul(ten) exp-- } for abs.GreaterThanOrEqual(ten) { abs = abs.Div(ten) exp++ } // 格式化系数 coeff := abs.StringFixed(int32(precision)) // 构造结果 return fmt.Sprintf("%sE%+d", coeff, exp) } // decimalFmtWithText0 12345678.987 转换为 12,345,679 func decimalFmtWithText0(d decimal.Decimal) string { p := message.NewPrinter(language.English) f, _ := d.Float64() return p.Sprintf("%.0f", f) } // decimalFmtWithText2 12345678.987 转换为 12,345,678.99 func decimalFmtWithText2(d decimal.Decimal) string { p := message.NewPrinter(language.English) f, _ := d.Float64() return p.Sprintf("%.2f", f) }