amount.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package common
  2. import (
  3. "math"
  4. "strconv"
  5. "strings"
  6. )
  7. // MoneyNegation 金额取反 负负得正
  8. func MoneyNegation(s string) string {
  9. switch {
  10. case s == "":
  11. return s
  12. case s[0] == '-':
  13. return s[1:]
  14. default:
  15. return "-" + s
  16. }
  17. }
  18. // IsAmountEqual 判断两个金额字符串是否相等
  19. func IsAmountEqual(amount1, amount2 string) bool {
  20. // 规范化金额字符串
  21. normalizedAmount1 := normalizeAmount(amount1)
  22. normalizedAmount2 := normalizeAmount(amount2)
  23. if normalizedAmount1 == "" {
  24. normalizedAmount1 = "0"
  25. }
  26. if normalizedAmount2 == "" {
  27. normalizedAmount2 = "0"
  28. }
  29. // 转换为浮点数进行比较
  30. value1, err1 := strconv.ParseFloat(normalizedAmount1, 64)
  31. value2, err2 := strconv.ParseFloat(normalizedAmount2, 64)
  32. // 如果任意一个转换失败,则认为不相等
  33. if err1 != nil || err2 != nil {
  34. return false
  35. }
  36. // 比较浮点数
  37. return math.Abs(value2-value1) < 0.0001
  38. }
  39. // normalizeAmount 规范化金额字符串
  40. func normalizeAmount(amount string) string {
  41. // 去掉逗号和多余的空格
  42. return strings.ReplaceAll(strings.TrimSpace(amount), ",", "")
  43. }
  44. // MoneyNormalize 金额标准化 "1,234.56" -> "1234.56"
  45. func MoneyNormalize(s string) string {
  46. return strings.ReplaceAll(s, ",", "")
  47. }
  48. // 金额字符串求和,要求金额字符串必须是整数且保留两位小数。
  49. func MoneyAdd(a, b string) string {
  50. // n = max(len(a), len(b))
  51. var n int
  52. if len(a) > len(b) {
  53. n = len(a)
  54. } else {
  55. n = len(b)
  56. }
  57. // 倒序求和
  58. // 123.45
  59. // + 67.89
  60. // --------
  61. // _191.34
  62. bs := make([]byte, n+1) // 可能有进位
  63. var carry byte
  64. for i := 1; i <= n; i++ {
  65. // 小数点
  66. if i == 3 {
  67. bs[n-i+1] = '.'
  68. continue
  69. }
  70. // 和 算数值
  71. c := byteOf(a, i) + byteOf(b, i) + carry
  72. if c >= 10 {
  73. carry = 1
  74. c -= 10
  75. } else {
  76. carry = 0
  77. }
  78. bs[n-i+1] = c + '0'
  79. }
  80. if carry != 0 {
  81. bs[0] = '1'
  82. return string(bs)
  83. }
  84. return string(bs[1:])
  85. }
  86. // 倒取字符串对应位算数值,超长取 0。
  87. //
  88. // byteOf("123.45", 1) -> 5
  89. // byteOf("67.89", 5) -> 0
  90. func byteOf(s string, i int) byte {
  91. if len(s) < i {
  92. return 0
  93. }
  94. return s[len(s)-i] - '0'
  95. }