| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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)
- }
|