一、数字转人民币
package main
import (
"fmt"
"math"
"strings"
)
var (
// 数字对应的大写中文
digits = []string{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}
// 整数部分的单位
units = []string{"", "拾", "佰", "仟"}
// 小数部分的单位
decimalUnits = []string{"分", "角"}
)
// ConvertToRMB 将数字转换为大写人民币格式
func ConvertToRMB(num float64) string {
if num == 0 {
return "零元整"
}
// 分离整数和小数部分
integerPart := int64(num)
decimalPart := int64(math.Round((num - float64(integerPart)) * 100))
// 处理整数部分
integerStr := convertInteger(integerPart)
// 处理小数部分
decimalStr := convertDecimal(decimalPart)
// 拼接结果
result := integerStr + "元"
if decimalStr == "" {
result += "整"
} else {
result += decimalStr
}
return result
}
// convertInteger 转换整数部分
func convertInteger(num int64) string {
if num == 0 {
return "零"
}
var resultArr []string
var tmp string
unitIndex := 0
for num > 0 {
digit := num % 10
if digit != 0 {
tmp = digits[digit] + units[unitIndex] + tmp
} else {
// 处理零的情况(避免连续多个零)
if tmp != "" && !strings.HasPrefix(tmp, "零") {
tmp = digits[digit] + tmp
}
}
num /= 10
unitIndex++
if unitIndex%4 == 0 {
resultArr = append(resultArr, tmp)
tmp = ""
unitIndex = 0
}
}
if len(tmp) > 0 {
resultArr = append(resultArr, tmp)
}
var result string
for i := len(resultArr) - 1; i >= 0; i-- {
if i == 2 {
result += resultArr[i] + "亿"
} else if i == 1 {
result += resultArr[i] + "万"
} else if i == 0 {
result += resultArr[i]
}
}
return result
}
// convertDecimal 转换小数部分
func convertDecimal(num int64) string {
if num == 0 {
return ""
}
var result string
for i := 0; i < len(decimalUnits) && num > 0; i++ {
digit := num % 10
if digit != 0 {
result = digits[digit] + decimalUnits[i] + result
}
num /= 10
}
return result
}
func main() {
testCases := []float64{
0,
0.5,
123.45,
1000.51,
1001.50,
1020.50,
1021.50,
1201.52,
10000.50,
123456789.99,
}
for _, num := range testCases {
fmt.Printf("%.2f -> %s\n", num, ConvertToRMB(num))
}
}
二、人民币转数字
步骤如下:
-
我们从左到右读取每个字符,如果是数字就先记下来,如果是单位就将记下来的数组乘以相应的倍数加到总和中。如五百三十六=(500)+(30)+6。但对于后面带万和亿的上面情况显然不符合。例如五百三十六万六千零三,按照上面计算方法为(500)+(30)+(60000),其实正确的做法应该是(500+30+6)*10000才对。
-
对于遇到“万”的情况,如五百三十六万六千零三,正确的拆分方式为:(五百三十六)万(六千零三)
-
同理对于遇到“亿”的情况,如一百二十亿三千三百八十三万六百六十六,正确的拆分方式为:(一百二十)亿(三千三百八十三)万(六百六十六)
-
特别的对于“万亿”也应该处理,如(二)万亿(零三千三百八十三)万(零六百六十六)
-
最后将上述每个“万”、“亿”、“万亿”分割的部分乘以相应的单位加到累加和中
举个栗子:
// 五百三十六万六千零三
// (一百二十)亿(三千三百八十三)万(零六百六十六)
// (三千三百八十三)万(零六百六十六)
// (六十六)万
//(二)万亿(零三千三百八十三)万(零六百六十六)
实现代码:
package main
import "fmt"
var CNNumbers = map[rune]int{'零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9}
var CNUnits = map[rune]int{'零': 1, '十': 10, '百': 100, '千': 1000, '万': 10000, '亿': 100000000}
// 五百三十六万六千零三
// (一百二十)亿(三千三百八十三)万(零六百六十六)
// (三千三百八十三)万(零六百六十六)
// (六十六)万
//(二)万亿(零三千三百八十三)万(零六百六十六)
func rmbToInt(numStr string) int {
res := 0
l, r := 0, 0
numStrs := []rune(numStr)
for r < len(numStrs) {
if numStrs[r] == '亿' {
res += _rmbToInt(string(numStrs[l:r])) * CNUnits['亿']
l = r + 1
} else if numStrs[r] == '万' {
if r+1 < len(numStrs) && numStrs[r+1] == '亿' {
res += _rmbToInt(string(numStrs[l:r])) * CNUnits['万'] * CNUnits['亿']
r = r + 1
l = r + 1
} else {
res += _rmbToInt(string(numStrs[l:r])) * CNUnits['万']
l = r + 1
}
}
r++
//fmt.Println("part:", l, r, numStr+":", res)
}
if l < r {
res += _rmbToInt(string(numStrs[l:r]))
}
fmt.Println(numStr+":", res)
return res
}
func _rmbToInt(numStr string) int {
res := 0
//和的每一部分
section := 0
for _, ch := range []rune(numStr) {
if digit, ok := CNNumbers[ch]; ok { //数字
section = digit
} else { //单位
if unit, ok := CNUnits[ch]; ok {
section *= unit
res += section
section = 0
}
}
}
res += section
//fmt.Println("part:", numStr, res)
return res
}
func main() {
rmbToInt("三千三百八十三万零六百六十六")
rmbToInt("六十六万")
rmbToInt("三千三百八十三万")
//rmbToInt("一百二十亿三千三百八十三万零六百六十六")
rmbToInt("二万亿三千三百八十三万零六百六十六")
rmbToInt("二万亿")
rmbToInt("一百万亿三千三百八十三万零六百六十六元")
rmbToInt("一百万亿三千三百八十三万零六百六十六元")
}