package common import ( "math" "strconv" "strings" ) // MoneyNegation 金额取反 负负得正 func MoneyNegation(s string) string { switch { case s == "": return s case s[0] == '-': return s[1:] default: return "-" + s } } // IsAmountEqual 判断两个金额字符串是否相等 func IsAmountEqual(amount1, amount2 string) bool { // 规范化金额字符串 normalizedAmount1 := normalizeAmount(amount1) normalizedAmount2 := normalizeAmount(amount2) if normalizedAmount1 == "" { normalizedAmount1 = "0" } if normalizedAmount2 == "" { normalizedAmount2 = "0" } // 转换为浮点数进行比较 value1, err1 := strconv.ParseFloat(normalizedAmount1, 64) value2, err2 := strconv.ParseFloat(normalizedAmount2, 64) // 如果任意一个转换失败,则认为不相等 if err1 != nil || err2 != nil { return false } // 比较浮点数 return math.Abs(value2-value1) < 0.0001 } // normalizeAmount 规范化金额字符串 func normalizeAmount(amount string) string { // 去掉逗号和多余的空格 return strings.ReplaceAll(strings.TrimSpace(amount), ",", "") } // MoneyNormalize 金额标准化 "1,234.56" -> "1234.56" func MoneyNormalize(s string) string { return strings.ReplaceAll(s, ",", "") } // 金额字符串求和,要求金额字符串必须是整数且保留两位小数。 func MoneyAdd(a, b string) string { // n = max(len(a), len(b)) var n int if len(a) > len(b) { n = len(a) } else { n = len(b) } // 倒序求和 // 123.45 // + 67.89 // -------- // _191.34 bs := make([]byte, n+1) // 可能有进位 var carry byte for i := 1; i <= n; i++ { // 小数点 if i == 3 { bs[n-i+1] = '.' continue } // 和 算数值 c := byteOf(a, i) + byteOf(b, i) + carry if c >= 10 { carry = 1 c -= 10 } else { carry = 0 } bs[n-i+1] = c + '0' } if carry != 0 { bs[0] = '1' return string(bs) } return string(bs[1:]) } // 倒取字符串对应位算数值,超长取 0。 // // byteOf("123.45", 1) -> 5 // byteOf("67.89", 5) -> 0 func byteOf(s string, i int) byte { if len(s) < i { return 0 } return s[len(s)-i] - '0' }