package money import ( "errors" "fmt" "strconv" "strings" ) // CentsPerYuan 是人民币元与分的固定换算比例。 const CentsPerYuan int64 = 100 var ErrInvalidYuan = errors.New("金额格式不正确") // ParseYuan 将用户输入的元字符串精确解析为分,不经过 float64。 // 支持 "12"、"12.3"、"12.34"、"-1.20";超过两位小数直接拒绝。 func ParseYuan(value string) (int64, error) { trimmed := strings.TrimSpace(value) if trimmed == "" { return 0, ErrInvalidYuan } sign := int64(1) if strings.HasPrefix(trimmed, "-") { sign = -1 trimmed = strings.TrimPrefix(trimmed, "-") } else if strings.HasPrefix(trimmed, "+") { trimmed = strings.TrimPrefix(trimmed, "+") } if trimmed == "" { return 0, ErrInvalidYuan } parts := strings.Split(trimmed, ".") if len(parts) > 2 { return 0, ErrInvalidYuan } wholeText := parts[0] if wholeText == "" { wholeText = "0" } whole, err := strconv.ParseInt(wholeText, 10, 64) if err != nil || whole < 0 { return 0, ErrInvalidYuan } fraction := int64(0) if len(parts) == 2 { fracText := parts[1] if len(fracText) > 2 { return 0, ErrInvalidYuan } fracText = fracText + strings.Repeat("0", 2-len(fracText)) if fracText == "" { fracText = "00" } fraction, err = strconv.ParseInt(fracText, 10, 64) if err != nil || fraction < 0 || fraction >= CentsPerYuan { return 0, ErrInvalidYuan } } if whole > (1<<62)/CentsPerYuan { return 0, ErrInvalidYuan } return sign * (whole*CentsPerYuan + fraction), nil } // Format 将分精确格式化为两位小数,例如 1234 -> "12.34"。 // 全程使用整数运算,不经过 float64,也不做四舍五入。 func Format(cent int64) string { sign := "" value := cent if value < 0 { sign = "-" value = -value } return fmt.Sprintf("%s%d.%02d", sign, value/CentsPerYuan, value%CentsPerYuan) } func FormatWithSymbol(cent int64) string { return "¥" + Format(cent) } func MinCent(a, b int64) int64 { if a < b { return a } return b } func MaxCent(a, b int64) int64 { if a > b { return a } return b }