找回密码
 欢迎注册
查看: 282|回复: 14

[讨论] 人民币金额大写的程序应该如何写?

[复制链接]
发表于 2025-2-25 11:10:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
人工智能写的代码太弱智了。
这样的代码应该如何写?具体流程是?
我目前能想到的办法就是穷举法!
但是穷举法太慢了。

比如
123456.78得到
壹拾贰万叁仟肆佰伍拾陆元柒角捌分

要是能像搜狗拼音一样就好了,
人工智能写的太差了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-25 12:44:55 | 显示全部楼层
https://blog.51cto.com/u_16213310/12989775

这儿有代码,看起来比人工智能写的靠谱多了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-25 21:55:27 | 显示全部楼层
将人民币金额数值转换为大写的算法可以通过以下步骤实现:

整数部分处理

先将金额的整数部分从右至左每四位分为一组,分别是个、万、亿等数级。例如,123456789.12可分为1|2345|6789,分别对应亿级、万级、个级。

从高位开始,对每一组数进行处理。对于每一组,按照个、十、百、千的顺序,将数字转换为对应的大写汉字,如0对应“零”,1对应“壹”,2对应“贰”等。例如,“2345”转换为“贰仟叁佰肆拾伍”。

在每一组数的后面加上相应的数级单位,如“亿”“万”等。但如果该组数字全为0,则省略该数级单位,不过当万级全为0时,要根据亿级和个级的情况来决定是否写“零”。例如,100005000,写成“壹亿零伍仟”。

小数部分处理

对于小数部分,将十分位和百分位的数字分别转换为大写汉字,如0.12转换为“壹角贰分”。如果十分位是0,可写成“零X分”,如0.05写成“零伍分”。

特殊情况处理

金额为0时,直接写成“零元整”。

当金额整数部分末尾是0,且小数部分为0时,要在整数部分大写后加上“整”字,如1000.00写成“壹仟元整”。

以下是一个Python示例代码实现该算法:

python
  
def convert_to_chinese_uppercase(amount):
    # 数字对应的大写汉字
    num_dict = {0: '零', 1: '壹', 2: '贰', 3: '叁', 4: '肆', 5: '伍', 6: '陆', 7: '柒', 8: '捌', 9: '玖'}
    # 数级单位
    unit_dict = ['', '拾', '佰', '仟', '万', '亿']

    integer_part, decimal_part = str(amount).split('.')
    integer_part = int(integer_part)
    decimal_part = int(decimal_part)

    if integer_part == 0 and decimal_part == 0:
        return '零元整'

    chinese_uppercase = ''
    # 处理整数部分
    if integer_part > 0:
        integer_str = str(integer_part)[::-1]
        for i in range(0, len(integer_str), 4):
            group = integer_str[i:i + 4][::-1]
            group_uppercase = ''
            for j, num in enumerate(group):
                num = int(num)
                if num!= 0:
                    group_uppercase += num_dict[num] + unit_dict[j]
            if group_uppercase!= '':
                if i // 4 == 1 and all(int(x) == 0 for x in integer_str[4:]):
                    chinese_uppercase = '万' + chinese_uppercase
                else:
                    chinese_uppercase = group_uppercase + unit_dict[i // 4 + 3] + chinese_uppercase

    # 处理小数部分
    if decimal_part > 0:
        chinese_uppercase +='元'
        if decimal_part // 10 > 0:
            chinese_uppercase += num_dict[decimal_part // 10] + '角'
        if decimal_part % 10 > 0:
            chinese_uppercase += num_dict[decimal_part % 10] + '分'
    else:
        chinese_uppercase +='元整'

    return chinese_uppercase

# 测试函数
amount = 123456789.12
print(convert_to_chinese_uppercase(amount))  
 

上述代码定义了一个函数 convert_to_chinese_uppercase ,它接受一个浮点数作为参数,将其转换为人民币大写金额的字符串并返回。代码中使用了两个字典 num_dict 和 unit_dict 来存储数字和数级单位的对应关系。先将金额分为整数部分和小数部分,然后分别对它们进行处理,最后将处理结果组合起来返回。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-26 09:58:48 | 显示全部楼层
搜狗输入法,v模式
输入v10^20.5,得到
10^20.5=3.16227766017e+20
三万一千六百二十二亿七千七百六十六万零一百六十八亿三千七百九十四万三千二百九十六元整
叁万壹仟陆佰贰拾贰亿柒仟柒佰陆拾陆万零壹佰陆拾捌亿叁仟柒佰玖拾肆万叁仟贰佰玖拾陆元整
为什么我感觉这个输出结果是错误的?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-26 10:02:20 | 显示全部楼层
nyy 发表于 2025-2-26 09:58
搜狗输入法,v模式
输入v10^20.5,得到
10^20.5=3.16227766017e+20

我发现了搜狗输入法的一个bug
输入
10^20.5 // IntegerPart
得到
316227766016837943296
输入
10^(41/2) // IntegerPart
得到
316227766016837933199

搜狗输入法,最后五位计算结果不正确

点评

可能内部数据结构不同。20.5为浮点数,41/2 为有理分数。我们知道 0.1=1/10,在二进制里,前者无法精确表达,但后者则可以。  发表于 2025-2-26 13:20
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-26 14:25:08 | 显示全部楼层
万、亿,后面的是?
万、亿后面的计数单位还有:

- 兆:1兆等于1万亿。

- 京:1京等于1万兆。

- 垓:1垓等于1万京。

- 秭:1秭等于1万垓。

- 穰:1穰等于1万秭。

- 沟:1沟等于1万穰。

- 涧:1涧等于1万沟。

- 正:1正等于1万涧。

- 载:1载等于1万正。

计数单位还有极、恒河沙、阿僧祇、那由他、不可思议、无量、大数等,且不同的文化和领域可能会有不同的使用习惯和更大的计数单位。

这个是人工智能的回答,也许有用
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-26 14:26:58 | 显示全部楼层
以下是这些计数单位与科学计数法的对应:

万:1万 = 10^{4}

亿:1亿 = 10^{8}

兆:1兆 = 10^{12}

京:1京 = 10^{16}

垓:1垓 = 10^{20}

秭:1秭 = 10^{24}

穰:1穰 = 10^{28}

沟:1沟 = 10^{32}

涧:1涧 = 10^{36}

正:1正 = 10^{40}

载:1载 = 10^{44}

如果继续往后,极对应的是10^{48},恒河沙是10^{52},阿僧祇是10^{56},那由他是10^{60},不可思议是10^{64},无量是10^{68},大数是10^{72}。

我感觉搜狗输入法结果不对
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-27 11:34:55 | 显示全部楼层
本帖最后由 nyy 于 2025-2-27 11:53 编辑
nyy 发表于 2025-2-26 14:26
以下是这些计数单位与科学计数法的对应:

万:1万 = 10^{4}

  1. '逆转字符串功能,输入abcd,则返回dcba
  2. Function ReverseString(ByVal str As String) As String
  3.     Dim i As Integer
  4.     Dim result As String
  5.     '默认结果初始值
  6.     result=""
  7.     '如果字符串的长度等于零,则返回空字符串
  8.     if Len(str)=0 then
  9.         ReverseString=str
  10.         Exit Function
  11.     end if
  12.     ' 遍历原字符串,从最后一个字符开始
  13.     For i = Len(str) To 1 Step -1
  14.         ' 将当前字符添加到结果字符串中
  15.         result = result & Mid(str, i, 1)
  16.     Next i
  17.     ReverseString = result
  18. End Function


  19. ' 函数名称:NumToChineseMoney
  20. ' 功能:将输入的人民币数字金额转换为大写金额
  21. ' 输入参数:
  22. '   num:要转换的数字金额,可以是整数或小数类型
  23. ' 返回参数:
  24. '   转换后的大写金额字符串
  25. Function NumToChineseMoney(ByVal num As Variant) As String
  26.     ' 存储数字 0 - 9 对应的大写汉字
  27.     Dim numDict(0 To 9) As String
  28.     ' 存储个、十、百、千单位
  29.     Dim unitDict(0 To 19) As String
  30.     ' 存储输入数字的整数部分的字符串形式
  31.     Dim integerPartStr As String
  32.     ' 存储输入数字的小数部分的字符串形式
  33.     Dim decimalPartStr As String
  34.     ' 存储转换后的整数部分大写金额
  35.     Dim integerPart As String
  36.     ' 存储转换后的小数部分大写金额
  37.     Dim decimalPart As String
  38.     ' 循环计数器,用于遍历数字字符串
  39.     Dim i As Integer
  40.     ' 存储当前处理的数字
  41.     Dim digit As Integer
  42.     ''''''''''''''''''''''''''''''''''''''''''
  43.     ' 初始化数字对应的大写汉字
  44.     numDict(0) = "零"
  45.     numDict(1) = "壹"
  46.     numDict(2) = "贰"
  47.     numDict(3) = "叁"
  48.     numDict(4) = "肆"
  49.     numDict(5) = "伍"
  50.     numDict(6) = "陆"
  51.     numDict(7) = "柒"
  52.     numDict(8) = "捌"
  53.     numDict(9) = "玖"
  54.     '将来扩展用
  55.     '        空        拾        佰        仟        万        1万 = 10^{4}
  56.     '                拾        佰        仟        亿        1亿 = 10^{8}
  57.     '                拾        佰        仟        兆        1兆 = 10^{12}
  58.     '                拾        佰        仟        京        1京 = 10^{16}
  59.     '                拾        佰        仟        垓        1垓 = 10^{20}
  60.     '                拾        佰        仟        秭        1秭 = 10^{24}
  61.     '                拾        佰        仟        穰        1穰 = 10^{28}
  62.     '                拾        佰        仟        沟        1沟 = 10^{32}
  63.     '                拾        佰        仟        涧        1涧 = 10^{36}
  64.     '                拾        佰        仟        正        1正 = 10^{40}
  65.     '                拾        佰        仟        载        1载 = 10^{44}
  66.     '初始化个、十、百、千单位
  67.     unitDict(0)=""
  68.     unitDict(1)="拾"
  69.     unitDict(2)="佰"
  70.     unitDict(3)="仟"
  71.     unitDict(4)="万"
  72.     unitDict(5)="拾"
  73.     unitDict(6)="佰"
  74.     unitDict(7)="仟"
  75.     unitDict(8)="亿"
  76.     unitDict(9)="拾"
  77.     unitDict(10)="佰"
  78.     unitDict(11)="仟"
  79.     unitDict(12)="兆"
  80.     unitDict(13)="拾"
  81.     unitDict(14)="佰"
  82.     unitDict(15)="仟"
  83.     unitDict(16)="京"
  84.     unitDict(17)="拾"
  85.     unitDict(18)="佰"
  86.     unitDict(19)="仟"
  87.     ''''''''''''''''''''''''''''''''''''''''''
  88.     ' 处理小数部分
  89.     If (num-int(num)<>0)Then
  90.         ' 将输入数字转换为字符串
  91.         Dim numStr As String
  92.         numStr = CStr(num)
  93.         ' 查找小数点的位置
  94.         Dim dotPos As Integer
  95.         dotPos = InStr(numStr, ".")
  96.         ' 提取整数部分的字符串
  97.         integerPartStr = Mid(numStr, 1, dotPos - 1)
  98.         ' 提取小数部分的字符串
  99.         decimalPartStr = Mid(numStr, dotPos + 1)
  100.         ' 确保小数部分为两位,不足两位补零
  101.         decimalPartStr = Mid(decimalPartStr & "00", 1, 2)
  102.         ' 如果小数部分不全为零,则进行转换
  103.         If decimalPartStr <> "00" Then
  104.             digit = Val(Mid(decimalPartStr, 1, 1))
  105.             If digit <> 0 Then
  106.                 decimalPart = decimalPart & numDict(digit) & "角"
  107.             End If
  108.             digit = Val(Mid(decimalPartStr, 2, 1))
  109.             If digit <> 0 Then
  110.                 decimalPart = decimalPart & numDict(digit) & "分"
  111.             End If
  112.         End If
  113.     Else
  114.         ' 如果输入是整数,直接将其转换为字符串作为整数部分
  115.         integerPartStr= CStr(num)
  116.     End If
  117.     ''''''''''''''''''''''''''''''''''''''''''
  118.     ' 处理整数部分
  119.     if Len(integerPartStr)>=20 then
  120.         MsgBox "数字太大,2024年中国GDP才134.91万亿元"
  121.         NumToChineseMoney="数字太大,2024年中国GDP才134.91万亿元"
  122.         Exit Function
  123.     End If
  124.     '把整数部分的字符串逆转,用循环加入单位
  125.     mystr=ReverseString(integerPartStr) '整数部分逆转后的字符串
  126.     integerPart=""
  127.     For i=0 to Len(mystr)-1 step 1
  128.         digit=val(Mid(mystr,i+1,1)) '这儿需要加1,否则bug
  129.         integerPart=numDict(digit) & unitDict(i) & integerPart
  130.     Next i
  131.     integerPart=Replace(integerPart,"零拾","零")
  132.     integerPart=Replace(integerPart,"零佰","零")
  133.     integerPart=Replace(integerPart,"零仟","零")
  134.     '把两个以上的零,合并成一个零(替换20次,应该够了)
  135.     integerPart=Replace(integerPart,"零零","零")
  136.     integerPart=Replace(integerPart,"零零","零")
  137.     integerPart=Replace(integerPart,"零零","零")
  138.     integerPart=Replace(integerPart,"零零","零")
  139.     integerPart=Replace(integerPart,"零零","零")
  140.     integerPart=Replace(integerPart,"零零","零")
  141.     integerPart=Replace(integerPart,"零零","零")
  142.     integerPart=Replace(integerPart,"零零","零")
  143.     integerPart=Replace(integerPart,"零零","零")
  144.     integerPart=Replace(integerPart,"零零","零")
  145.     integerPart=Replace(integerPart,"零零","零")
  146.     integerPart=Replace(integerPart,"零零","零")
  147.     integerPart=Replace(integerPart,"零零","零")
  148.     integerPart=Replace(integerPart,"零零","零")
  149.     integerPart=Replace(integerPart,"零零","零")
  150.     integerPart=Replace(integerPart,"零零","零")
  151.     integerPart=Replace(integerPart,"零零","零")
  152.     integerPart=Replace(integerPart,"零零","零")
  153.     integerPart=Replace(integerPart,"零零","零")
  154.     integerPart=Replace(integerPart,"零零","零")
  155.     '这些单位,放在后面替换,特殊
  156.     integerPart=Replace(integerPart,"零万","万")
  157.     integerPart=Replace(integerPart,"零亿","亿")
  158.     integerPart=Replace(integerPart,"零兆","兆")
  159.     integerPart=Replace(integerPart,"零京","京")
  160.     ''''''''''''''''''''''''''''''''''''''''''
  161.     If integerPart = "" Then
  162.         ' 如果整数部分为空,设为零
  163.         integerPart = "零"
  164.     End If
  165.     ' 添加元
  166.     integerPart = integerPart & "元"
  167.     ''''''''''''''''''''''''''''''''''''''''''
  168.     ' 合并整数部分和小数部分
  169.     NumToChineseMoney = integerPart & decimalPart
  170.     If decimalPart = "" Then
  171.         ' 如果没有小数部分,添加整字
  172.         NumToChineseMoney = NumToChineseMoney & "整"
  173.     End If
  174. End Function

  175. Sub TestNumToChineseMoney()
  176.     Dim number As Double
  177.     Dim result As String
  178.    
  179.     ' 示例 1:整数
  180.     number = 1000000001.23
  181.     result = NumToChineseMoney(number)
  182.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  183.    
  184.     ' 示例 2:带小数
  185.     number = 123.45
  186.     result = NumToChineseMoney(number)
  187.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  188.    
  189.     ' 示例 3:小数为零
  190.     number = 123.00
  191.     result = NumToChineseMoney(number)
  192.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  193.    
  194.     ' 示例 4:整数为零
  195.     number = 0.45
  196.     result = NumToChineseMoney(number)
  197.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  198. End Sub
复制代码


先传一个有bug的代码上来,主要是零的处理的问题,
比如
  1. 1000000001        壹拾亿万零壹元整
  2. 12345678.12        壹仟贰佰叁拾肆万伍仟陆佰柒拾捌元壹角贰分
复制代码

不知道什么时候能优化好!

1000000001        壹拾亿万零壹元整
这个结果显然错误。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-27 12:07:57 | 显示全部楼层
nyy 发表于 2025-2-27 11:34
先传一个有bug的代码上来,主要是零的处理的问题,
比如
  1. '逆转字符串功能,输入abcd,则返回dcba
  2. Function ReverseString(ByVal str As String) As String
  3.     Dim i As Integer
  4.     Dim result As String
  5.     '默认结果初始值
  6.     result=""
  7.     '如果字符串的长度等于零,则返回空字符串
  8.     if Len(str)=0 then
  9.         ReverseString=str
  10.         Exit Function
  11.     end if
  12.     ' 遍历原字符串,从最后一个字符开始
  13.     For i = Len(str) To 1 Step -1
  14.         ' 将当前字符添加到结果字符串中
  15.         result = result & Mid(str, i, 1)
  16.     Next i
  17.     ReverseString = result
  18. End Function


  19. ' 函数名称:NumToChineseMoney
  20. ' 功能:将输入的人民币数字金额转换为大写金额
  21. ' 输入参数:
  22. '   num:要转换的数字金额,可以是整数或小数类型
  23. ' 返回参数:
  24. '   转换后的大写金额字符串
  25. Function NumToChineseMoney(ByVal num As Variant) As String
  26.     ' 存储数字 0 - 9 对应的大写汉字
  27.     Dim numDict(0 To 9) As String
  28.     ' 存储个、十、百、千单位
  29.     Dim unitDict(0 To 19) As String
  30.     ' 存储输入数字的整数部分的字符串形式
  31.     Dim integerPartStr As String
  32.     ' 存储输入数字的小数部分的字符串形式
  33.     Dim decimalPartStr As String
  34.     ' 存储转换后的整数部分大写金额
  35.     Dim integerPart As String
  36.     ' 存储转换后的小数部分大写金额
  37.     Dim decimalPart As String
  38.     ' 循环计数器,用于遍历数字字符串
  39.     Dim i As Integer
  40.     ' 存储当前处理的数字
  41.     Dim digit As Integer
  42.     ''''''''''''''''''''''''''''''''''''''''''
  43.     ' 初始化数字对应的大写汉字
  44.     numDict(0) = "零"
  45.     numDict(1) = "壹"
  46.     numDict(2) = "贰"
  47.     numDict(3) = "叁"
  48.     numDict(4) = "肆"
  49.     numDict(5) = "伍"
  50.     numDict(6) = "陆"
  51.     numDict(7) = "柒"
  52.     numDict(8) = "捌"
  53.     numDict(9) = "玖"
  54.     '将来扩展用
  55.     '        空        拾        佰        仟        万        1万 = 10^{4}
  56.     '                拾        佰        仟        亿        1亿 = 10^{8}
  57.     '                拾        佰        仟        兆        1兆 = 10^{12}
  58.     '                拾        佰        仟        京        1京 = 10^{16}
  59.     '                拾        佰        仟        垓        1垓 = 10^{20}
  60.     '                拾        佰        仟        秭        1秭 = 10^{24}
  61.     '                拾        佰        仟        穰        1穰 = 10^{28}
  62.     '                拾        佰        仟        沟        1沟 = 10^{32}
  63.     '                拾        佰        仟        涧        1涧 = 10^{36}
  64.     '                拾        佰        仟        正        1正 = 10^{40}
  65.     '                拾        佰        仟        载        1载 = 10^{44}
  66.     '初始化个、十、百、千单位
  67.     unitDict(0)=""
  68.     unitDict(1)="拾"
  69.     unitDict(2)="佰"
  70.     unitDict(3)="仟"
  71.     unitDict(4)="万" '特殊
  72.     unitDict(5)="拾"
  73.     unitDict(6)="佰"
  74.     unitDict(7)="仟"
  75.     unitDict(8)="亿" '特殊
  76.     unitDict(9)="拾"
  77.     unitDict(10)="佰"
  78.     unitDict(11)="仟"
  79.     unitDict(12)="兆" '特殊
  80.     unitDict(13)="拾"
  81.     unitDict(14)="佰"
  82.     unitDict(15)="仟"
  83.     unitDict(16)="京" '特殊
  84.     unitDict(17)="拾"
  85.     unitDict(18)="佰"
  86.     unitDict(19)="仟"
  87.     ''''''''''''''''''''''''''''''''''''''''''
  88.     ' 处理小数部分
  89.     If (num-int(num)<>0)Then
  90.         ' 将输入数字转换为字符串
  91.         Dim numStr As String
  92.         numStr = CStr(num)
  93.         ' 查找小数点的位置
  94.         Dim dotPos As Integer
  95.         dotPos = InStr(numStr, ".")
  96.         ' 提取整数部分的字符串
  97.         integerPartStr = Mid(numStr, 1, dotPos - 1)
  98.         ' 提取小数部分的字符串
  99.         decimalPartStr = Mid(numStr, dotPos + 1)
  100.         ' 确保小数部分为两位,不足两位补零
  101.         decimalPartStr = Mid(decimalPartStr & "00", 1, 2)
  102.         ' 如果小数部分不全为零,则进行转换
  103.         If decimalPartStr <> "00" Then
  104.             digit = Val(Mid(decimalPartStr, 1, 1))
  105.             If digit <> 0 Then
  106.                 decimalPart = decimalPart & numDict(digit) & "角"
  107.             End If
  108.             digit = Val(Mid(decimalPartStr, 2, 1))
  109.             If digit <> 0 Then
  110.                 decimalPart = decimalPart & numDict(digit) & "分"
  111.             End If
  112.         End If
  113.     Else
  114.         ' 如果输入是整数,直接将其转换为字符串作为整数部分
  115.         integerPartStr= CStr(num)
  116.     End If
  117.     ''''''''''''''''''''''''''''''''''''''''''
  118.     ' 处理整数部分
  119.     if Len(integerPartStr)>=20 then
  120.         MsgBox "数字太大,2024年中国GDP才134.91万亿元"
  121.         NumToChineseMoney="数字太大,2024年中国GDP才134.91万亿元"
  122.         Exit Function
  123.     End If
  124.     '把整数部分的字符串逆转,用循环加入单位
  125.     mystr=ReverseString(integerPartStr) '整数部分逆转后的字符串
  126.     integerPart=""
  127.     For i=0 to Len(mystr)-1 step 1
  128.         digit=val(Mid(mystr,i+1,1)) '这儿需要加1,否则bug
  129.         integerPart=numDict(digit) & unitDict(i) & integerPart
  130.     Next i
  131.     integerPart=Replace(integerPart,"零拾","零")
  132.     integerPart=Replace(integerPart,"零佰","零")
  133.     integerPart=Replace(integerPart,"零仟","零")
  134.     '把两个以上的零,合并成一个零
  135.     integerPart=Replace(integerPart,"零零零零","零")
  136.     integerPart=Replace(integerPart,"零零零","零")
  137.     integerPart=Replace(integerPart,"零零","零")
  138.     '这些单位,放在后面替换,特殊
  139.     integerPart=Replace(integerPart,"京零兆","京")
  140.     integerPart=Replace(integerPart,"京零亿","京")
  141.     integerPart=Replace(integerPart,"京零万","京")
  142.     integerPart=Replace(integerPart,"兆零亿","兆")
  143.     integerPart=Replace(integerPart,"兆零万","兆")
  144.     integerPart=Replace(integerPart,"亿零万","亿")
  145.     integerPart=Replace(integerPart,"零京","京")
  146.     integerPart=Replace(integerPart,"零兆","兆")
  147.     integerPart=Replace(integerPart,"零亿","亿")
  148.     integerPart=Replace(integerPart,"零万","万")
  149.     ''''''''''''''''''''''''''''''''''''''''''
  150.     If integerPart = "" Then
  151.         ' 如果整数部分为空,设为零
  152.         integerPart = "零"
  153.     End If
  154.     ' 添加元
  155.     integerPart = integerPart & "元"
  156.     ''''''''''''''''''''''''''''''''''''''''''
  157.     ' 合并整数部分和小数部分
  158.     NumToChineseMoney = integerPart & decimalPart
  159.     If decimalPart = "" Then
  160.         ' 如果没有小数部分,添加整字
  161.         NumToChineseMoney = NumToChineseMoney & "整"
  162.     End If
  163. End Function

  164. Sub TestNumToChineseMoney()
  165.     Dim number As Double
  166.     Dim result As String
  167.    
  168.     ' 示例 1:整数
  169.     number = 1000000001.23
  170.     result = NumToChineseMoney(number)
  171.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  172.    
  173.     ' 示例 2:带小数
  174.     number = 123.45
  175.     result = NumToChineseMoney(number)
  176.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  177.    
  178.     ' 示例 3:小数为零
  179.     number = 123.00
  180.     result = NumToChineseMoney(number)
  181.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  182.    
  183.     ' 示例 4:整数为零
  184.     number = 0.45
  185.     result = NumToChineseMoney(number)
  186.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  187. End Sub
复制代码


优化了一下代码,如果不超过20位,应该没问题
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2025-2-27 12:24:38 | 显示全部楼层
nyy 发表于 2025-2-27 12:07
优化了一下代码,如果不超过20位,应该没问题
  1. '逆转字符串功能,输入abcd,则返回dcba
  2. Function ReverseString(ByVal str As String) As String
  3.     Dim i As Integer
  4.     Dim result As String
  5.     '默认结果初始值
  6.     result=""
  7.     '如果字符串的长度等于零,则返回空字符串
  8.     if Len(str)=0 then
  9.         ReverseString=str
  10.         Exit Function
  11.     end if
  12.     ' 遍历原字符串,从最后一个字符开始
  13.     For i = Len(str) To 1 Step -1
  14.         ' 将当前字符添加到结果字符串中
  15.         result = result & Mid(str, i, 1)
  16.     Next i
  17.     ReverseString = result
  18. End Function


  19. ' 函数名称:NumToChineseMoney
  20. ' 功能:将输入的人民币数字金额转换为大写金额
  21. ' 输入参数:
  22. '   num:要转换的数字金额,可以是整数或小数类型
  23. ' 返回参数:
  24. '   转换后的大写金额字符串
  25. Function NumToChineseMoney(ByVal num As Variant) As String
  26.     ' 存储数字 0 - 9 对应的大写汉字
  27.     Dim numDict(0 To 9) As String
  28.     ' 存储个、十、百、千单位
  29.     Dim unitDict(0 To 19) As String
  30.     ' 存储输入数字的整数部分的字符串形式
  31.     Dim integerPartStr As String
  32.     ' 存储输入数字的小数部分的字符串形式
  33.     Dim decimalPartStr As String
  34.     ' 存储转换后的整数部分大写金额
  35.     Dim integerPart As String
  36.     ' 存储转换后的小数部分大写金额
  37.     Dim decimalPart As String
  38.     ' 循环计数器,用于遍历数字字符串
  39.     Dim i As Integer
  40.     ' 存储当前处理的数字
  41.     Dim digit As Integer
  42.     ''''''''''''''''''''''''''''''''''''''''''
  43.     ' 初始化数字对应的大写汉字
  44.     numDict(0) = "零"
  45.     numDict(1) = "壹"
  46.     numDict(2) = "贰"
  47.     numDict(3) = "叁"
  48.     numDict(4) = "肆"
  49.     numDict(5) = "伍"
  50.     numDict(6) = "陆"
  51.     numDict(7) = "柒"
  52.     numDict(8) = "捌"
  53.     numDict(9) = "玖"
  54.     '将来扩展用
  55.     '        空        拾        佰        仟        万        1万 = 10^{4}
  56.     '                拾        佰        仟        亿        1亿 = 10^{8}
  57.     '                拾        佰        仟        兆        1兆 = 10^{12}
  58.     '                拾        佰        仟        京        1京 = 10^{16}
  59.     '                拾        佰        仟        垓        1垓 = 10^{20}
  60.     '                拾        佰        仟        秭        1秭 = 10^{24}
  61.     '                拾        佰        仟        穰        1穰 = 10^{28}
  62.     '                拾        佰        仟        沟        1沟 = 10^{32}
  63.     '                拾        佰        仟        涧        1涧 = 10^{36}
  64.     '                拾        佰        仟        正        1正 = 10^{40}
  65.     '                拾        佰        仟        载        1载 = 10^{44}
  66.     '初始化个、十、百、千单位
  67.     unitDict(0)=""
  68.     unitDict(1)="拾"
  69.     unitDict(2)="佰"
  70.     unitDict(3)="仟"
  71.     unitDict(4)="万" '特殊
  72.     unitDict(5)="拾"
  73.     unitDict(6)="佰"
  74.     unitDict(7)="仟"
  75.     unitDict(8)="亿" '特殊
  76.     unitDict(9)="拾"
  77.     unitDict(10)="佰"
  78.     unitDict(11)="仟"
  79.     unitDict(12)="兆" '特殊
  80.     unitDict(13)="拾"
  81.     unitDict(14)="佰"
  82.     unitDict(15)="仟"
  83.     unitDict(16)="京" '特殊
  84.     unitDict(17)="拾"
  85.     unitDict(18)="佰"
  86.     unitDict(19)="仟"
  87.     ''''''''''''''''''''''''''''''''''''''''''
  88.     ' 处理小数部分
  89.     If (num-int(num)<>0)Then
  90.         ' 将输入数字转换为字符串
  91.         Dim numStr As String
  92.         numStr = CStr(num)
  93.         ' 查找小数点的位置
  94.         Dim dotPos As Integer
  95.         dotPos = InStr(numStr, ".")
  96.         ' 提取整数部分的字符串
  97.         integerPartStr = Mid(numStr, 1, dotPos - 1)
  98.         ' 提取小数部分的字符串
  99.         decimalPartStr = Mid(numStr, dotPos + 1)
  100.         ' 确保小数部分为两位,不足两位补零
  101.         decimalPartStr = Mid(decimalPartStr & "00", 1, 2)
  102.         ' 如果小数部分不全为零,则进行转换
  103.         If decimalPartStr <> "00" Then
  104.             digit = Val(Mid(decimalPartStr, 1, 1))
  105.             If digit <> 0 Then
  106.                 decimalPart = decimalPart & numDict(digit) & "角"
  107.             End If
  108.             digit = Val(Mid(decimalPartStr, 2, 1))
  109.             If digit <> 0 Then
  110.                 decimalPart = decimalPart & numDict(digit) & "分"
  111.             End If
  112.         End If
  113.     Else
  114.         ' 如果输入是整数,直接将其转换为字符串作为整数部分
  115.         integerPartStr= CStr(num)
  116.     End If
  117.     ''''''''''''''''''''''''''''''''''''''''''
  118.     ' 处理整数部分
  119.     ' 如果整数部分太大,则返回错误.
  120.     if Len(integerPartStr)>20 then
  121.         MsgBox "数字太大,2024年中国GDP才134.91万亿元(1.3491*10^14)"
  122.         NumToChineseMoney="数字太大,2024年中国GDP才134.91万亿元(1.3491*10^14)"
  123.         Exit Function
  124.     End If
  125.     '把整数部分的字符串逆转,用循环加入单位
  126.     mystr=ReverseString(integerPartStr) '整数部分逆转后的字符串
  127.     integerPart=""
  128.     For i=0 to Len(mystr)-1 step 1
  129.         digit=val(Mid(mystr,i+1,1)) '这儿需要加1,否则bug
  130.         integerPart=numDict(digit) & unitDict(i) & integerPart
  131.     Next i
  132.     integerPart=Replace(integerPart,"零拾","零")
  133.     integerPart=Replace(integerPart,"零佰","零")
  134.     integerPart=Replace(integerPart,"零仟","零")
  135.     '把两个以上的零,合并成一个零
  136.     integerPart=Replace(integerPart,"零零零零","零")
  137.     integerPart=Replace(integerPart,"零零零","零")
  138.     integerPart=Replace(integerPart,"零零","零")
  139.     '这些单位,放在后面替换,特殊
  140.     integerPart=Replace(integerPart,"京零兆","京")
  141.     integerPart=Replace(integerPart,"京零亿","京")
  142.     integerPart=Replace(integerPart,"京零万","京")
  143.     integerPart=Replace(integerPart,"兆零亿","兆")
  144.     integerPart=Replace(integerPart,"兆零万","兆")
  145.     integerPart=Replace(integerPart,"亿零万","亿")
  146.     integerPart=Replace(integerPart,"零京","京")
  147.     integerPart=Replace(integerPart,"零兆","兆")
  148.     integerPart=Replace(integerPart,"零亿","亿")
  149.     integerPart=Replace(integerPart,"零万","万")
  150.     ''''''''''''''''''''''''''''''''''''''''''
  151.     If integerPart = "" Then
  152.         ' 如果整数部分为空,设为零
  153.         integerPart = "零"
  154.     End If
  155.     ' 添加元
  156.     integerPart = integerPart & "元"
  157.     '避免出现"京零元"这样的问题
  158.     integerPart=Replace(integerPart,"京零元","京元")
  159.     integerPart=Replace(integerPart,"兆零元","兆元")
  160.     integerPart=Replace(integerPart,"亿零元","亿元")
  161.     integerPart=Replace(integerPart,"万零元","万元")
  162.     ''''''''''''''''''''''''''''''''''''''''''
  163.     ' 合并整数部分和小数部分
  164.     NumToChineseMoney = integerPart & decimalPart
  165.     If decimalPart = "" Then
  166.         ' 如果没有小数部分,添加整字
  167.         NumToChineseMoney = NumToChineseMoney & "整"
  168.     End If
  169. End Function

  170. Sub TestNumToChineseMoney()
  171.     Dim number As Double
  172.     Dim result As String
  173.    
  174.     ' 示例 1:整数
  175.     number = 1000000001.23
  176.     result = NumToChineseMoney(number)
  177.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  178.    
  179.     ' 示例 2:带小数
  180.     number = 123.45
  181.     result = NumToChineseMoney(number)
  182.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  183.    
  184.     ' 示例 3:小数为零
  185.     number = 123.00
  186.     result = NumToChineseMoney(number)
  187.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  188.    
  189.     ' 示例 4:整数为零
  190.     number = 0.45
  191.     result = NumToChineseMoney(number)
  192.     MsgBox "数字 " & number & " 转换后的大写金额是:" & result
  193. End Sub
复制代码


继续优化代码,这样估计没bug了!

点评

nyy
0000_0000_0000_0000_0000 00000000000000000000 京元整 有这个bug  发表于 2025-2-27 12:28
nyy
对于00000000000000000000 京元整 这算一个bug  发表于 2025-2-27 12:27
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2025-3-26 14:04 , Processed in 0.063237 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表