money.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package money
  2. import (
  3. "strings"
  4. "github.com/shopspring/decimal"
  5. )
  6. func Yuan2Fen(price float64) int64 {
  7. return decimal.NewFromFloat(price).Mul(decimal.New(1, 2)).IntPart()
  8. }
  9. func Fen2Yuan(price uint64) float64 {
  10. //分除以100得到元
  11. d := decimal.New(1, 2)
  12. result, _ := decimal.NewFromInt(int64(price)).DivRound(d, 2).Float64()
  13. return result
  14. }
  15. var (
  16. numUpper = []string{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}
  17. unitInt = []string{"", "拾", "佰", "仟"} // 个、十、百、千
  18. unitSec = []string{"", "万", "亿", "万亿"} // 万级单位
  19. unitDec = []string{"角", "分"} // 小数单位
  20. )
  21. func AmountToChinese(amount float64) string {
  22. if amount == 0 {
  23. return "零元整"
  24. }
  25. // 处理负数
  26. prefix := ""
  27. if amount < 0 {
  28. prefix = "负"
  29. amount = -amount
  30. }
  31. // 转成整数(分)
  32. n := int64(amount*100 + 0.5)
  33. intPart := n / 100 // 整数部分
  34. decPart := n % 100 // 小数部分
  35. result := prefix + integerToChinese(intPart)
  36. // 小数部分处理
  37. if decPart == 0 {
  38. return result + "元整"
  39. }
  40. result += "元"
  41. jiao := decPart / 10
  42. fen := decPart % 10
  43. if jiao > 0 {
  44. result += numUpper[jiao] + unitDec[0] // 角
  45. } else if fen > 0 {
  46. result += "零" // 无角有分,如 0.05 → “零”
  47. }
  48. if fen > 0 {
  49. result += numUpper[fen] + unitDec[1] // 分
  50. } else {
  51. result += "整" // 无分,加“整”
  52. }
  53. return result
  54. }
  55. // 整数金额转大写
  56. func integerToChinese(num int64) string {
  57. if num == 0 {
  58. return "零"
  59. }
  60. var res string
  61. secIdx := 0 // 万、亿、万亿
  62. for num > 0 {
  63. section := num % 10000
  64. if section != 0 {
  65. sectionStr := sectionToChinese(section)
  66. if secIdx > 0 {
  67. sectionStr += unitSec[secIdx]
  68. }
  69. res = sectionStr + res
  70. } else {
  71. if !strings.HasPrefix(res, "零") {
  72. res = "零" + res
  73. }
  74. }
  75. num /= 10000
  76. secIdx++
  77. }
  78. // 清理多余“零”
  79. res = strings.TrimLeft(res, "零")
  80. for strings.Contains(res, "零零") {
  81. res = strings.ReplaceAll(res, "零零", "零")
  82. }
  83. res = strings.TrimRight(res, "零")
  84. return res
  85. }
  86. // 每个 4 位小节(0~9999)
  87. func sectionToChinese(section int64) string {
  88. var str string
  89. unitPos := 0
  90. zeroFlag := false
  91. for section > 0 {
  92. digit := section % 10
  93. if digit == 0 {
  94. if !zeroFlag && len(str) > 0 {
  95. str = "零" + str
  96. }
  97. zeroFlag = true
  98. } else {
  99. str = numUpper[digit] + unitInt[unitPos] + str
  100. zeroFlag = false
  101. }
  102. unitPos++
  103. section /= 10
  104. }
  105. return str
  106. }