注册 登录
编程论坛 ASP.NET技术论坛

小数转换成大写中文(最终版出炉)

走刀口→超 发布于 2008-04-22 16:42, 2885 次点击
4.23日:最终版在17楼,欢迎大家测试使用哈!


今天在做账单,要这个功能的函数。
自己写了一个,给大家分享一下。代码比较丑,有高手顺便改改么?
我这个现在支持int的2位的小数都可以。可是公司的人告诉我要改下,如果有3位小数就有问题了。我的确汗中。
一下是代码,大家有兴趣玩玩看看用用哈!
程序代码:
protected string FormatAmount(string amount)
    {
        string str = "";
        char[] TOBIG = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
        char[] TOUNIT = { '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟' };

        if (amount[amount.Length - 3] == '.')
        {
            for (int i = 0; i < amount.Length - 3; i++)
            {
                int j = amount.Length - 4 - i;
                if (amount[i] == '0')
                {
                    for (int k = i; k < amount.Length - 1; k++)
                    {
                        if (amount[i + 1] == '0' || amount[i + 1] == '.')
                            i++;
                    }
                    if (i == amount.Length - 1)
                        str += "整";
                    else
                        str += TOBIG[0];
                }
                else
                {
                    str += TOBIG[int.Parse(amount[i].ToString())].ToString();
                    str += TOUNIT[j].ToString();
                }
            }
            if (amount[amount.Length - 2] != '0')
                str += TOBIG[int.Parse(amount[amount.Length - 2].ToString())].ToString() + "角";
            if (amount[amount.Length - 1] != '0')
                str += TOBIG[int.Parse(amount[amount.Length - 1].ToString())].ToString() + "分";
        }
        else
        {
            for (int i = 0; i < amount.Length; i++)
            {
                int j = amount.Length - 1 - i;
                if (amount[i] == '0')
                {
                    if (amount[i + 1] == '0')
                        i++;
                    if (i == amount.Length - 1)
                        str += "整";
                    else
                        str += TOBIG[0];
                }
                else
                {
                    str += TOBIG[int.Parse(amount[i].ToString())].ToString();
                    str += TOUNIT[j].ToString();
                }
            }
        }
        return str;
    }


谢谢各位看了!

[[it] 本帖最后由 走刀口→超 于 2008-4-23 11:14 编辑 [/it]]
18 回复
#2
hebingbing2008-04-22 17:03
忒牛了……
这绝对是首创……
从来没有见过这么有意义的代码……
#3
走刀口→超2008-04-22 17:07
-。-LS不要取笑我了。
本来我写的是switch...case被经理说了顿。

#4
走刀口→超2008-04-22 17:44
新版本,才弄的,放在论坛上回家还能看看。
支持了多位小数。。。不过肯定还少了个整。T.T

程序代码:
protected string FormatAmount(string amount)
    {
        string str = "";
        char[] TOBIG = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
        char[] TOUNIT = { '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟' };
        char[] TOUNITDE = { '角', '分', '里'};
        string amount1 = "";
        string amount2 = "";
        int dot = amount.IndexOf('.');
        if (dot == -1)
        {
            dot = amount.Length;
            amount1 = amount.Substring(0, dot);
        }
        else
        {
            amount1 = amount.Substring(0, dot);
            amount2 = amount.Substring(++dot , amount.Length - dot);
        }

        for (int i = 0; i < amount1.Length; i++)
        {
            int j = amount1.Length - 1 - i;
            if (amount1[i] == '0')
            {
                if (amount1[i + 1] == '0')
                    i++;
                if (i == amount1.Length - 1)
                    str += "整";
                else
                    str += TOBIG[0];
            }
            else
            {
                str += TOBIG[int.Parse(amount1[i].ToString())].ToString();
                str += TOUNIT[j].ToString();
            }
        }
        if (dot != amount.Length)
        {
            for (int i = 0; i < amount2.Length; i++)
            {
                str += TOBIG[int.Parse(amount2[i].ToString())].ToString();
                str += i > 2 ? "" : TOUNITDE[i].ToString();
            }
        }
#5
走刀口→超2008-04-22 17:45
我也想不出什么多位后面的单位了。。。谁想想。哈哈。
#6
淡漠的茶2008-04-22 19:30
private string GetUP(double Price)
    {
        char[] TOBIG = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
        int bw = (int)(Price / 1000000);
        double tsw = (Price - bw * 1000000);
        int sw = (int)(tsw / 100000);
        double tw = (tsw - sw * 100000);
        int w = (int)(tw / 10000);
        double tq = (tw - w * 10000);
        int q = (int)(tq / 1000);
        double tb = (tq - q * 1000);
        int b = (int)(tb / 100);
        double ts = (tb - b * 100);
        int s = (int)(ts / 10);
        int y = (int)(ts % 10);
        double tp = (int)((ts - s * 10 - y) * 100);
        int j = (int)(tp / 10);
        int f = (int)(tp % 10);
        string ot = char[bw]+"佰"+char[sw]+"拾"+char[w]+"萬"+char[q]+"仟"+char[b]+"佰"+char[s]+"拾"+char[y]+"圆"+char[j]+"角"+char[f]+"分";
        return ot;
    }

我这个就比较郁闷了,哈哈,前段时间写的一个精确WEB控制打印出(入)库单里写的,只到百万,和分,因为超不过百万,也不会有厘出现
#7
淡漠的茶2008-04-22 19:48
不采用循环的原因是想显示成0000001.22 这样的效果,哈哈
#8
走刀口→超2008-04-22 19:51
哪有0000001.22这样的价格哦。。。这样不好。这个价格不切实际!出现小数后3位的我已经不能接受了!
#9
淡漠的茶2008-04-22 19:51
Convet.Int32会四随五入
(int)强转换不会
#10
淡漠的茶2008-04-22 19:54
有的,出库单 入库单 发票需要写成这样
因为采用打印,无法辨别字体的,别人完全可以前在前面加打印
要么用人民币符号,要么用零封死
不管是数字还是大写前面都要封死
还因为这些单子的格式本来就是固定的,得充满封死
采用大写本来的作用就是防止改动,不然就会出现康熙遗昭传位十四子变传位于四子,光大写了还不行,还得前后封死。封死就安全了,因为打印报表中不可能出现 二十百万的这样的情况的,又不是老外的那种表示方法

如果不是打印,不是形成纸张形式,你转换大写就完全是多此一举,根本没必要。打印你就必须封,你可以问问你们财务是不是这个规则

再牛的代码如果你不契合实际需要也是白搭的,金钱慎重

[[it] 本帖最后由 淡漠的茶 于 2008-4-22 20:12 编辑 [/it]]
#11
淡漠的茶2008-04-22 19:56
这就防止财务 库管 客户做手脚,涉及到钱这个问题是很现实的
我建议如果你是要打印,你也要封死前面和后面
#12
淡漠的茶2008-04-22 20:00
假如一张出库单,如果不封死,你完全可以在前面加,因为在你手里保存的有2-3联,收出库单的只有一联,完全可以说他伪造你签名,可以向他多要钱
或者在库管财务那个环节被变动了,涉及到钱的问题一定要谨慎
#13
淡漠的茶2008-04-22 20:02
或者涉及到外贸,原来是人民币结算,给你前面加个美圆符号(要是财务跟客户勾结,三联全加),你哭都不知道找谁哭

[[it] 本帖最后由 淡漠的茶 于 2008-4-22 20:08 编辑 [/it]]
#14
走刀口→超2008-04-22 20:13
饿,很有道理。。。

大写的话要看打在哪了。大写一般不太好造假吧。

至于小写,我后面有个单位,前面在去家个¥,呼呼!
#15
淡漠的茶2008-04-22 20:20
大写可以再前面加 一亿这样的
如果实际帐目前都是零,你就没法加,加了也没意义。比如零亿零千零百零十伍万,前面全用大写零封死,这样就只有到伍万才有意义,具化到分其实也是后封的意思,如果只以万为基本单位,到万后面就没了,你要么后面全用零封住(这个时候也需要用“整”这个字封,防止加单位),要么就在万后面用整封住

[[it] 本帖最后由 淡漠的茶 于 2008-4-22 20:25 编辑 [/it]]
#16
走刀口→超2008-04-22 20:27
要考虑下的。不过我现在做的单子不太可能出现这种状况。

毕竟我做的单子是双方都应该知道的。
#17
走刀口→超2008-04-23 11:13
最终完美版,无论是什么数据进来,都让你变成中文大写。KAO。

不要太超过大小就好了。哈哈。支持到了万亿这种单位。

原来之前没问问财务,"整"和"零"给我弄错地方了,浪费SO多的时间。o(∩_∩)o...哈哈,好在现在OK了!

大家有兴趣的测试测试,可能还有BUG。。。刚刚还调了2个。汗!

程序代码:
public static string FormatAmount(string amount)
    {
        //定义
        string str = "";
        char[] TOBIG = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
        char[] TOUNIT = { '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟', '万' };
        char[] TOUNITDE = { '角', '分', '厘', '毫', '丝' };

        string amount1 = "";
        string amount2 = "";
        int dot = amount.IndexOf('.');
        int start = 0;

        //获取非0的开始位置
        for (int i = 0; i <= dot; i++)
            if (amount[i] == '0')
                start++;
            else
                break;

        //把数字分段
        if (dot == -1)
        {
            dot = amount.Length;
            amount1 = amount.Substring(0, dot);
        }
        else
        {
            if (start == 0)
                amount1 = amount.Substring(start, dot);
            else
            {
                int length = dot - start;
                amount1 = amount.Substring(start, length);
            }
            amount2 = amount.Substring(++dot, amount.Length - dot);
        }

        //转化整数位
        int n = 0;
        for (int i = 0; i < amount1.Length; i++)
        {
            int j = amount1.Length - 1 - i;
            n = i;
            if (amount1[i] == '0')
            {
                for (int k = i; k < amount1.Length - 1; k++)
                {
                    if (amount1[i + 1] == '0')
                        i++;
                    else
                        break;
                }
                if (i != n || (amount1.Length - n - 1) % 4 == 0)
                {
                    if (j >= 8)
                        str += TOUNIT[8].ToString();
                    else if (j >= 4)
                        str += TOUNIT[4].ToString();
                    else
                        if (amount1.Length == 1 || i != amount1.Length - 1)
                            str += "";
                }
                else
                    str += TOBIG[0].ToString();
            }
            else
            {
                str += TOBIG[int.Parse(amount1[i].ToString())].ToString();
                str += j == 0 ? "" : TOUNIT[j].ToString();
            }
        }

        if (amount1.Length != 0)
            str += TOUNIT[0].ToString();

        if (amount2.Length == 0)
            str += "整";

        //转化小数位
        if (dot != amount.Length)
        {
            int flag = 0;
            for (int i = 0; i < amount2.Length; i++)
            {
                if (amount2[i] == '0')
                {
                    for (int k = i; k < amount2.Length - 1; k++)
                        if (amount2[i + 1] == '0')
                            i++;
                        else
                            break;
                    if (i == amount2.Length - 1 && flag == 0 && amount1.Length != 0)
                        str += "整";
                    else
                        if (amount1.Length == 0 && flag == 0)
                            str += TOBIG[0].ToString() + TOUNIT[0].ToString();
                        else if (amount1.Length == 0 || i == amount2.Length - 1)
                            str += "";
                        else
                            str += TOBIG[0].ToString();
                }
                else
                {
                    flag = 1;
                    str += TOBIG[int.Parse(amount2[i].ToString())].ToString();
                    str += i > 4 ? "" : TOUNITDE[i].ToString();
                }
            }
        }
        return str;
    }


[[it] 本帖最后由 走刀口→超 于 2008-4-25 16:09 编辑 [/it]]
#18
hebingbing2008-04-23 16:09
最经在搞一个基于ajax的商城交易平台,我想你的这个东西我或许要用的到的……
呵呵……
1