这个代码是2003年写的了.当时用的是vc6.已在pudn网站公开过了,
近来看到这样一个消息:微软的Visual   Studio   Internationalization   Pack包含East   Asia   Numeric   Formatting   Library
已经有这样的转换功能,但我还没来得及细看.虽然这段代码很短,但是经过较多的测试,并且符合国家标准.我希望它可以挑战其他转换算法(我既希望我的算法是最好的,但是我更希望看到更好的算法).
        public static string GetChineseNum(string strType, string strIn)
        {            string m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9;
            //m_1
            m_1 = strIn;
            string numNum = "0123456789.";
            string numChina = "零壹贰叁肆伍陆柒捌玖点";
            string numChinaWeigh = "个拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿";
            //m_1.Format("%.2f", atof(m_1));
            m_1 = (float.Parse(strIn)).ToString("f2");
            m_2 = m_1;
            m_3 = m_4 = "";
            //m_2:1234->壹贰叁肆
            for (int i = 0; i < 11; i++)
            {
                //m_2=m_2.Replace(numNum.Mid(i, 1), numChina.Mid(i * 2, 2));
                m_2 = m_2.Replace(numNum.Substring(i, 1), numChina.Substring(i, 1));
            }            //m_3:佰拾万仟佰拾个
            int iLen = m_1.Length;
            if (iLen > 16)
            {
                m_8 = m_9 = "越界错!";
                return "";
            }
            if (m_1.IndexOf('.') > 0)
                iLen = m_1.IndexOf('.');            for (int i = iLen; i >= 1; i--)
            {
                m_3 += numChinaWeigh.Substring(i - 1, 1);
            }
            //m_4:2行+3行            for (int i = 0; i < m_3.Length; i++)
            {
                m_4 += m_2.Substring(i, 1) + m_3.Substring(i, 1);
            }
            //m_5:4行去"0"后拾佰仟            m_5 = m_4;
            m_5 = m_5.Replace("零拾", "零");
            m_5 = m_5.Replace("零佰", "零");
            m_5 = m_5.Replace("零仟", "零");
            //m_6:00->0,000->0            m_6 = m_5;
            for (int i = 0; i < iLen; i++)
                m_6 = m_6.Replace("零零", "零");            //m_7:6行去亿,万,个位"0"
            m_7 = m_6;
            m_7 = m_7.Replace("亿零万零", "亿零");
            m_7 = m_7.Replace("亿零万", "亿零");
            m_7 = m_7.Replace("零亿", "亿");
            m_7 = m_7.Replace("零万", "万");
            if (m_7.Length > 2)
                m_7 = m_7.Replace("零个", "个");            //m_8:7行+2行小数->数目
            m_8 = m_7;
            m_8 = m_8.Replace("个", "");
            if (m_2.Substring(m_2.Length - 3, 3) != "点零零")
                m_8 += m_2.Substring(m_2.Length - 3, 3);            //m_9:7行+2行小数->价格
            m_9 = m_7;
            m_9 = m_9.Replace("个", "圆");
            if (m_2.Substring(m_2.Length - 3, 3) != "点零零")
            {
                m_9 += m_2.Substring(m_2.Length - 2, 2);
                m_9 = m_9.Insert(m_9.Length - 1, "角");
                m_9 += "分";
            }
            else m_9 += "整";
            if (m_9 != "零圆整")
                m_9 = m_9.Replace("零圆", "");
            m_9 = m_9.Replace("零分", "整");
            if (strType == "数量")
                return m_8;
            else
                return m_9;        }

解决方案 »

  1.   

    使用:
    string sPrice = SomeStaticClass.GetChineseNum("价格","123.45");//得到价格
    string sCount = SomeStaticClass.GetChineseNum("数量","123.45");//得到数量
      

  2.   

    挑战 East Asia  Numeric  Formatting Library !
      

  3.   

    这段代码写的时间应该是1个小时左右,但是断断续续测试修改的时间确多得多.可能是写代码时间的几十和上百倍.代码的成熟和算法的完整度测试真是不容易呀,我现在都懒得再测试了,因为我自己都测试厌烦了.所以我希望大家猛烈的挑刺,让我有所收获.我现在已经挑出一处了,       
    if   (iLen   >   16) 

          m_8   =   m_9   =   "越界错!"; 
          return   ""; 

    其中
    m_8   =   m_9   =   "越界错!"; 
    是无效代码.
      

  4.   

    中间的m_1,m_2....m_9主要是显示转换过程,如果要代码的最精简,还可做适当优化.
      

  5.   

    首先,"我为编程狂"的学习精神值得我敬佩.其对 正则表达式 的理解,很不得了.
    既然是擂台,就要比较.我觉得在可读性,易读性和效率上,我的算法仍然是领先的(鄙视自己一下,又在自夸了).
    下面是效率测试,10万次连续转换
    using System;
    using System.Text;
    using System.Text.RegularExpressions;namespace 大写金额转换效率比较
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTime dt1 = DateTime.Now;
                string s1 = "";
                string s2="";
                for (int i = 0; i < 100000; i++)
                {
                    s1 = SomeStaticClass.GetPrice("100100100001.23");            }
                TimeSpan ts = DateTime.Now - dt1; ;
                System.Console.WriteLine(s1 + " calcu " + 100000.ToString() + "times elapsed " + ts.TotalMilliseconds.ToString() + "ms");
                DateTime dt2 = DateTime.Now;
                for (int i = 0; i < 100000; i++)
                {
                    s2 = SomeStaticClass.LGGetPrice("100100100001.23");
                }
                TimeSpan ts2 = DateTime.Now - dt2; ;
                System.Console.WriteLine(s2 + " calcu " + 100000.ToString() + "times elapsed " + ts2.TotalMilliseconds.ToString() + "ms");
            }
        }
        static class SomeStaticClass
        { 
            public static string GetPrice(string sIn)//我为编程狂写的
            {
                return Regex.Replace(Regex.Replace(Decimal.Parse(sIn).ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A"), @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\.]|$))))", "${b}${z}"), ".", delegate(Match m) { return "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString(); });
            }
            public static string LGGetPrice(string sIn)//fckadxz写的
            {
                string s1="";
                string s2="";
                string s3="";            string numNum = "0123456789.";
                string numChina = "零壹贰叁肆伍陆柒捌玖点";
                string numChinaWeigh = "个拾佰仟萬拾佰仟亿拾佰仟萬拾佰仟亿";            s1 = (Decimal.Parse(sIn)).ToString("f2");
                int iLen = s1.Length; 
                if (iLen > 16)
                {
                    return "";
                }    
                if (s1.IndexOf('.') > 0)
                    iLen = s1.IndexOf('.');
                //s1:1234->壹贰叁肆
                for (int i = 0; i < 11; i++)
                {
                    s1 = s1.Replace(numNum.Substring(i, 1), numChina.Substring(i, 1));
                }            //s2:佰拾萬仟佰拾个
                for (int i = iLen; i >= 1; i--)
                {
                    s2 += numChinaWeigh.Substring(i - 1, 1);
                }            //s3:s1+s2
                for (int i = 0; i < s2.Length; i++)
                {
                    s3 += s1.Substring(i, 1) + s2.Substring(i, 1);
                }            //s3去"0"后拾佰仟
                s3 = s3.Replace("零拾", "零");
                s3 = s3.Replace("零佰", "零");
                s3 = s3.Replace("零仟", "零");            //s3:00->0,000->0
                for (int i = 0; i < iLen; i++)
                    s3 = s3.Replace("零零", "零");            //s3:去亿,万,个位"0"
                s3 = s3.Replace("亿零萬零", "亿零");
                s3 = s3.Replace("亿零萬", "亿零");
                s3 = s3.Replace("零亿", "亿");
                s3 = s3.Replace("零萬", "萬");
                if (s3.Length > 2)
                    s3 = s3.Replace("零个", "个");
                s3 = s3.Replace("个", "圆");
                if (s1.Substring(s1.Length - 3, 3) != "点零零")
                {
                    s3 += s1.Substring(s1.Length - 2, 2);
                    s3 = s3.Insert(s3.Length - 1, "角");
                    s3 += "分";
                }
                else s3 += "整";
                if (s3 != "零圆整")
                    s3 = s3.Replace("零圆", "");
                return s3;
            }
        }
    }
    结果是4958ms:2000ms.
    我写的程序暂时领先.
      

  6.   

    对不起大家,我这里停电,马上把程序贴上.我的小代码比过了微软的那个什么East Asia  Numeric Formatting Library.要想运行下面程序,到http://www.microsoft.com/Downloads/details.aspx?FamilyID=e432aeaa-7b6f-4b0d-968b-b6aafda05e34&displaylang=en下载一个vsipk1beta.zip的文件,展开后有个文件是EANumFormat.msi,如果你的系统装了vs2005或2008,就可以安装它和使用里面的East Asia  Numeric Formatting Library.建好项目工程,还要引入这个库才能顺利编译.
      

  7.   

    using System;
    using Microsoft.International.Formatters;
    using System.Globalization;
    using System.Diagnostics;
    using System.Text.RegularExpressions;namespace Example_LocalNumericFormat
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTime dt1 = DateTime.Now;
                string s1 = "";
                string s2 = "";
                string s3 = "";
                string sIn = "100100100001";
                int iCount = 100000;
                for (int i = 0; i < iCount; i++)
                {
                    s1 = SomeStaticClass.GetPrice(sIn);            }
                TimeSpan ts = DateTime.Now - dt1; ;
                System.Console.WriteLine("我为编程狂写的:"+s1 + " calcu " + iCount.ToString() + "times elapsed " + ts.TotalMilliseconds.ToString() + "ms");
                DateTime dt2 = DateTime.Now;
                for (int i = 0; i < iCount; i++)
                {
                    s2 = SomeStaticClass.LGGetPrice(sIn);
                }
                TimeSpan ts2 = DateTime.Now - dt2; ;
                System.Console.WriteLine("fckadxz 写的:"+s2 + " calcu " + iCount.ToString() + "times elapsed " + ts2.TotalMilliseconds.ToString() + "ms");            DateTime dt3 = DateTime.Now;
                for (int i = 0; i < iCount; i++)
                {
                    s3 = SomeStaticClass.MsGetPrice(sIn);
                }
                TimeSpan ts3 = DateTime.Now - dt3; ;
                System.Console.WriteLine("microsoft 写的:"+s3 + " calcu " + iCount.ToString() + "times elapsed " + ts3.TotalMilliseconds.ToString() + "ms");
            }
        }
        static class SomeStaticClass
        {
            public static string GetPrice(string sIn)//我为编程狂写的
            {
                return Regex.Replace(Regex.Replace(Decimal.Parse(sIn).ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A"), @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\.]|$))))", "${b}${z}"), ".", delegate(Match m) { return "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString(); });
            }
            public static string LGGetPrice(string sIn)//fckadxz写的
            {
                string s1 = "";
                string s2 = "";
                string s3 = "";            string numNum = "0123456789.";
                string numChina = "零壹贰叁肆伍陆柒捌玖点";
                string numChinaWeigh = "个拾佰仟萬拾佰仟亿拾佰仟萬拾佰仟亿";            s1 = (Decimal.Parse(sIn)).ToString("f2");
                int iLen = s1.Length;
                if (iLen > 16)
                {
                    return "";
                }
                if (s1.IndexOf('.') > 0)
                    iLen = s1.IndexOf('.');
                //s1:1234->壹贰叁肆
                for (int i = 0; i < 11; i++)
                {
                    s1 = s1.Replace(numNum.Substring(i, 1), numChina.Substring(i, 1));
                }            //s2:佰拾萬仟佰拾个
                for (int i = iLen; i >= 1; i--)
                {
                    s2 += numChinaWeigh.Substring(i - 1, 1);
                }            //s3:s1+s2
                for (int i = 0; i < s2.Length; i++)
                {
                    s3 += s1.Substring(i, 1) + s2.Substring(i, 1);
                }            //s3去"0"后拾佰仟
                s3 = s3.Replace("零拾", "零");
                s3 = s3.Replace("零佰", "零");
                s3 = s3.Replace("零仟", "零");            //s3:00->0,000->0
                for (int i = 0; i < iLen; i++)
                    s3 = s3.Replace("零零", "零");            //s3:去亿,万,个位"0"
                s3 = s3.Replace("亿零萬零", "亿零");
                s3 = s3.Replace("亿零萬", "亿零");
                s3 = s3.Replace("零亿", "亿");
                s3 = s3.Replace("零萬", "萬");
                if (s3.Length > 2)
                    s3 = s3.Replace("零个", "个");
                s3 = s3.Replace("个", "圆");
                if (s1.Substring(s1.Length - 3, 3) != "点零零")
                {
                    s3 += s1.Substring(s1.Length - 2, 2);
                    s3 = s3.Insert(s3.Length - 1, "角");
                    s3 += "分";
                }
                else s3 += "整";
                if (s3 != "零圆整")
                    s3 = s3.Replace("零圆", "");
                return s3;
            }
            public static string MsGetPrice(string sIn)//微软的
            {
                return string.Format(new EastAsiaNumericFormatter(), "{0:L}", Decimal.Parse(sIn));
            }
        }}
      

  8.   

    我的机器是xp3200+ 1G内存,运行时间 4265ms:1812ms:2359ms.
    我的算法小小领先.庆祝一下!
    微软的算法不是很完善,人家也说了是bata版,可能自己也不太满意.期待他能做的更好.
    这也说明,只要专心做事,可以做的甚至比微软要好!和csdn的网友们一起努力!
      

  9.   

    我也来一个:
    // 数字转换成大写金额(C#实现)
    // 例如:(new Money(200)).ToString() == "贰佰元"
    namespace Skyiv.Util
    {
      using System.Text;  class Test
      {
        static void Main()
        {
          for (;;)
          {
            System.Console.Write("金额: ");
            string  s = System.Console.ReadLine();
            decimal m;
            try   { m = decimal.Parse(s); }
            catch { break; }
            System.Console.WriteLine("大写: " + new Money(m));
          }
        }
      }  // 该类重载的 ToString() 方法返回的是大写金额字符串
      class Money
      {
        public string Yuan  = "元";                        // “元”,可以改为“圆”、“卢布”之类
        public string Jiao  = "角";                        // “角”,可以改为“拾”
        public string Fen   = "分";                        // “分”,可以改为“美分”之类
        static string Digit = "零壹贰叁肆伍陆柒捌玖";      // 大写数字
        bool   isAllZero    = true;                        // 片段内是否全零
        bool   isPreZero    = true;                        // 低一位数字是否是零
        bool   Overflow     = false;                       // 溢出标志
        long   money100;                                   // 金额*100,即以“分”为单位的金额
        long   value;                                      // money100的绝对值
        StringBuilder sb    = new StringBuilder();         // 大写金额字符串,逆序    // 只读属性: "零元"
        public string ZeroString
        {
          get { return Digit[0] + Yuan; }
        }    // 构造函数
        public Money(decimal money)
        {
          try   { money100 = (long)(money * 100m); }
          catch { Overflow = true; }
          if (money100 == long.MinValue) Overflow = true;
        }    // 重载 ToString() 方法,返回大写金额字符串
        public override string ToString()
        {
          if (Overflow) return "金额超出范围";
          if (money100 == 0) return ZeroString;
          string [] Unit = { Yuan, "万", "亿", "万", "亿亿" };
          value = System.Math.Abs(money100);
          ParseSection(true);
          for (int i = 0; i < Unit.Length && value > 0; i++)
          {
            if (isPreZero && !isAllZero) sb.Append(Digit[0]);
            if (i == 4 && sb.ToString().EndsWith(Unit[2]))
              sb.Remove(sb.Length - Unit[2].Length, Unit[2].Length);
            sb.Append(Unit[i]);
            ParseSection(false);
            if ((i % 2) == 1 && isAllZero)
              sb.Remove(sb.Length - Unit[i].Length, Unit[i].Length);
          }
          if (money100 < 0) sb.Append("负");
          return Reverse();
        }    // 解析“片段”: “角分(2位)”或“万以内的一段(4位)”
        void ParseSection(bool isJiaoFen)
        {
          string [] Unit = isJiaoFen ?
            new string [] { Fen, Jiao } :
            new string [] { "", "拾", "佰", "仟" };
          isAllZero = true;
          for (int i = 0; i < Unit.Length && value > 0; i++)
          {
            int d = (int)(value % 10);
            if (d != 0)
            {
              if (isPreZero && !isAllZero) sb.Append(Digit[0]);
              sb.AppendFormat("{0}{1}", Unit[i], Digit[d]);
              isAllZero = false;
            }
            isPreZero = (d == 0);
            value /= 10;
          }
        }    // 反转字符串
        string Reverse()
        {
          StringBuilder sbReversed = new StringBuilder();
          for (int i = sb.Length - 1; i >= 0; i--)
            sbReversed.Append(sb[i]);
          return sbReversed.ToString();
        }
      }
    }
      

  10.   

    http://topic.csdn.net/u/20080125/09/04c65875-4f50-42cd-bd63-d7b1429e42e1.html
    这里贴上网友 我为编程狂 用 正则表达式 写的同样功能程序的连接.他说他用了3天还熬夜,对他这种忘我工作和独辟蹊径表示尊重.
      

  11.   

    using System;class Money2
    {
      static void Main()
      {
        string s1     = "900000.468";
        string s2     = "8000000234";
        string sPrice = SomeStaticClass.GetChineseNum("价格", s1);
        string sCount = SomeStaticClass.GetChineseNum("数量", s2);
        Console.WriteLine("{0}: {1}", s1, sPrice);
        Console.WriteLine("{0}: {1}", s2, sCount); 
      }
    }/*
    程序输出:
    900000.468: 玖拾万圆肆角整
    8000000234: 捌拾亿
    似乎精度不够。
    */
      

  12.   

    wuyi8808:您的程序测试了下,比我的更快些,大概是10万次转换800ms的样子.而且有位数短耗时更少的特性.
    想来stringbuilder对字符串操作.会快于string的一般操作.
    我终于看到了更好的算法!有空了要研究研究.非常高兴,谢谢!
      

  13.   

    回21楼wuyi8808,您说的对,我在16楼已经改过来了.
      

  14.   

    1楼我的程序原来的错误出现在
    m_1=(float.Parse(strIn)).ToString("f2"); 
    应改用Decimal.Pars代替float.Pars.
      

  15.   

    class Test
    {
      static void Main()
      {
        string s1      = "9999999999999.99";
        string s2      = "10000000000000";
        string sPrice1 = SomeStaticClass.LGGetPrice(s1);
        string sPrice2 = SomeStaticClass.LGGetPrice(s2);
        System.Console.WriteLine("{0}: {1}", s1, sPrice1);
        System.Console.WriteLine("{0}: {1}", s2, sPrice2);
      }
    }
    /*
    不错,16楼的程序已经不会丢失精度了:
    9999999999999.99: 玖萬玖仟玖佰玖拾玖亿玖仟玖佰玖拾玖萬玖仟玖佰玖拾玖圆玖角玖分
    10000000000000: 
    看来只能处理13位整数。
    */
      

  16.   

    建议楼主把代码放在 [code=C#]...[/code] 之间,这样代码看起来更清晰些。
      

  17.   


    if   (iLen   >   16) //iLen包含了小数点和2位小数,所以被限定13位整数.但这个程序要调整精度却非常简单.

         return   ""; 
      

  18.   

    仅仅需要修改 string   numChinaWeigh   =   "个拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿"; //向右边扩展提高精度
    和if   (iLen   >   16) //可以改变16到更大的数字.

         return   ""; 
    }就可以实现精度扩展
      

  19.   

    这个可以转换 "900000000000000000000000000.03";        public static string LGGetPrice(string sIn)//fckadxz写的
            {
                string s1 = "";
                string s2 = "";
                string s3 = "";            string numNum = "0123456789.";
                string numChina = "零壹贰叁肆伍陆柒捌玖点";
                string numChinaWeigh = "个拾佰仟萬拾佰仟亿拾佰仟萬拾佰仟亿拾佰仟萬拾佰仟亿拾佰仟萬拾佰仟亿";            s1 = (Decimal.Parse(sIn)).ToString("f2");
                int iLen = s1.Length;
                if (iLen > 32)
                {
                    return "";
                }
                if (s1.IndexOf('.') > 0)
                    iLen = s1.IndexOf('.');
                //s1:1234->壹贰叁肆
                for (int i = 0; i < 11; i++)
                {
                    s1 = s1.Replace(numNum.Substring(i, 1), numChina.Substring(i, 1));
                }            //s2:佰拾萬仟佰拾个
                for (int i = iLen; i >= 1; i--)
                {
                    s2 += numChinaWeigh.Substring(i - 1, 1);
                }            //s3:s1+s2
                for (int i = 0; i < s2.Length; i++)
                {
                    s3 += s1.Substring(i, 1) + s2.Substring(i, 1);
                }            //s3去"0"后拾佰仟
                s3 = s3.Replace("零拾", "零");
                s3 = s3.Replace("零佰", "零");
                s3 = s3.Replace("零仟", "零");            //s3:00->0,000->0
                for (int i = 0; i < iLen; i++)
                    s3 = s3.Replace("零零", "零");            //s3:去亿,万,个位"0"
                s3 = s3.Replace("亿零萬零", "亿零");
                s3 = s3.Replace("亿零萬", "亿零");
                s3 = s3.Replace("零亿", "亿");
                s3 = s3.Replace("零萬", "萬");
                if (s3.Length > 2)
                    s3 = s3.Replace("零个", "个");
                s3 = s3.Replace("个", "圆");
                if (s1.Substring(s1.Length - 3, 3) != "点零零")
                {
                    s3 += s1.Substring(s1.Length - 2, 2);
                    s3 = s3.Insert(s3.Length - 1, "角");
                    s3 += "分";
                }
                else s3 += "整";
                if (s3 != "零圆整")
                    s3 = s3.Replace("零圆", "");
                return s3;
            }
      

  20.   

    21 楼提到的精度问题,是因为你提供的是 double 变量,你改成 900000.468M 就行了。微软那个实际上也是转 decimal 然后才转换的。
    我这个用正则表达式 3 行转换的,能实现四舍五入,能转 decimal 最大值。详细说明见
    http://topic.csdn.net/u/20080125/09/04c65875-4f50-42cd-bd63-d7b1429e42e1.html
    31楼-33楼
    using System;
    using System.Text.RegularExpressions;class Program
    {
        static void Main()
        {
            string s = (new Random().Next()/100.0).ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A");
            string d = Regex.Replace(s, @"((?<=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\.]|$))))", "${b}${z}");
            Console.WriteLine(d + "\n" + Regex.Replace(d, ".", delegate(Match m) { return "负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰"[m.Value[0] - '-'].ToString(); }));
        }
    }
      

  21.   

      我把微软的代码反编译出来,去掉了类型安全检查等功能,所以参数由装箱的 object 改为了直接用 decimal,修改后执行结果如下:我为编程狂写的:壹仟零壹億零壹拾萬零壹圆整   calcu   100000times   elapsed   1422
    .0448ms(自微软源码改编)
    fckadxz   写的:壹仟零壹亿零壹拾萬零壹圆整   calcu   100000times   elapsed   5618
    .0784ms
    空间Ⅳ    写的:壹仟零壹亿零壹拾万零壹元   calcu   100000times   elapsed   1251
    .8ms  还是没有空间Ⅳ的快,不过我是一直用128位的 decimal 计算,而空间Ⅳ用64位的 long,计算范围大,如果也改成 64 位的long,应该能更快,能达到这个速度说明代码很成功。微软的核心代码不论架构还是效率都非常的高。但最后由于外层的派生类提供多语言支持等原因损失了些性能。楼主不要轻易拿自己 56 秒的代码说比微软的 14 秒的代码还快。
      

  22.   

    这里有我今晚操刀的新作,思路是按照人的阅读习惯,从左到右的读出来.速度比微软的快10倍,也比 空间Ⅳ 的算法快到了 2倍左右.public static string GetNumFromLeft2Right(string sIn)//fckadxz 2008 写的
            {
                long d = long.Parse(sIn);
                string sNum = "零壹贰叁肆伍陆柒捌玖";
                string sWeight = "仟亿拾佰仟萬拾佰";
                StringBuilder sb = new StringBuilder();
                int[] iWeight = new int[sIn.Length];
                int[] iValue = new int[sIn.Length];
                for (int i = 0; i < sIn.Length; i++)
                {
                    iWeight[i] = (sIn.Length - i) % 8;
                    iValue[sIn.Length - i - 1] = (int)(d % 10);
                    d = d / 10;
                }
                int iCount = 1;
                int iNext = 0;
                for (int i = 0; i < sIn.Length; i++)
                {
                    if (sIn[i] > '0')
                    {
                        sb.Append(sNum[iValue[i]]);
                        if (i < sIn.Length - 1)
                            sb.Append(sWeight[iWeight[i]]);
                        iNext = i + 1;
                    }
                    else if (iWeight[i] == 1)
                    {
                        if (i < sIn.Length - 1)
                            sb.Append("亿");
                        else
                            break;
                    }
                    else if (iWeight[i] == 5 && (i < 4 || sIn.Substring(i - 3, 4) != "0000"))
                        sb.Append("万");
                    else if (i < iNext)
                        continue;
                    else //处理出现的连续0的第一个0
                    {
                        iCount = 1;
                        for (int j = i + 1; j < sIn.Length; j++)
                        {
                            if (iValue[j] == 0 && iWeight[j] != 0)
                            {
                                iCount++;
                                continue;
                            }
                            else
                                break;
                        }
                        iNext = i + iCount;                    if (iWeight[i] == 0)//千万
                        {
                            if (iCount == 8)
                                continue;
                            else
                                sb.Append("零");
                        }
                        else if (iWeight[i] == 7)//百万
                        {
                            if (iCount == 3)
                                continue;
                            else
                                sb.Append("零");
                        }
                        else if (iWeight[i] == 6)//十万
                        {
                            if (iCount == 2)
                                continue;
                            else
                                sb.Append("零");
                        }
                        else if (iWeight[i] == iCount)//千百十
                            continue;
                        else
                            sb.Append("零");
                    }
                }
                return sb.ToString();
            }
      

  23.   

    有点小问题,又改了下.//采用从左到右,直接读出的办法
    public static string GetNumFromLeft2Right(string sIn)//fckadxz 2008 写的
    {
        long d = long.Parse(sIn);
        if (d == 0)
            return "零";
        string sNum = "零壹贰叁肆伍陆柒捌玖";
        string sWeight = "仟亿拾佰仟萬拾佰";
        StringBuilder sb = new StringBuilder();
        int[] iWeight = new int[sIn.Length];
        int[] iValue = new int[sIn.Length];
        for (int i = 0; i < sIn.Length; i++)
        {
            iWeight[i] = (sIn.Length - i) % 8;
            iValue[sIn.Length - i - 1] = (int)(d % 10);
            d = d / 10;
        }
        int iCount = 1;
        int iNext = 0;
        for (int i = 0; i < sIn.Length; i++)
        {
            if (sIn[i] > '0')
            {
                sb.Append(sNum[iValue[i]]);
                if (i < sIn.Length - 1)
                    sb.Append(sWeight[iWeight[i]]);
                iNext = i + 1;
            }
            else if (iWeight[i] == 1)
            {
                if (i < sIn.Length - 1)
                    sb.Append("亿");
            }
            else if (iWeight[i] == 5 )
            {
                if(i < 4 || sIn.Substring(i - 3, 4) != "0000")
                sb.Append("萬");
            }
            else if (i < iNext)
                continue;
            else //处理出现的连续0的第一个0
            {
                iCount = 1;
                for (int j = i + 1; j < sIn.Length && iValue[j] == 0 && iWeight[j] != 0; j++)
                      iCount++;
                iNext = i + iCount;            if (iWeight[i] == 0)//千万
                {
                    if (iCount != 8)
                        sb.Append("零");
                }
                else if (iWeight[i] == 7)//百万
                {
                    if (iCount != 3)
                        sb.Append("零");
                }
                else if (iWeight[i] == 6)//十万
                {
                    if (iCount != 2)
                        sb.Append("零");
                }
                else if (iWeight[i] != iCount)//千百十
                    sb.Append("零");
            }
        }
        return sb.ToString();
    }
      

  24.   

    一觉醒来,找出点bug,再改.public static string GetNumFromLeft2Right(string sIn)//fckadxz 2008 写的
    {
        long d = long.Parse(sIn);
        if (d == 0)
            return "零";
        string sNum = "零壹贰叁肆伍陆柒捌玖";
        string sWeight = "仟亿拾佰仟萬拾佰";
        StringBuilder sb = new StringBuilder();
        int[] iWeight = new int[sIn.Length];
        int[] iValue = new int[sIn.Length];
        for (int i = 0; i < sIn.Length; i++)
        {
            iWeight[i] = (sIn.Length - i) % 8;
            iValue[sIn.Length - i - 1] = (int)(d % 10);
            d = d / 10;
        }
        int iCount = 1;
        int iNext = 0;
        bool bZeroAfterWan = false;
        for (int i = 0; i < sIn.Length; i++)
        {
            if (sIn[i] > '0')
            {
                sb.Append(sNum[iValue[i]]);
                if (i < sIn.Length - 1)
                    sb.Append(sWeight[iWeight[i]]);
                iNext = i + 1;
            }
            else if (iWeight[i] == 1)
            {
                if (i < sIn.Length - 1)
                    sb.Append("亿");
            }
            else if (iWeight[i] == 5)
            {
                if (i < 4 || iValue[i - 3] + iValue[i - 2] + iValue[i - 1] > 0)
                {
                    sb.Append("萬");
                    if (bZeroAfterWan)
                    {
                        sb.Append("零");
                        bZeroAfterWan = false;
                    }
                }
            }
            else if (i < iNext)
                continue;
            else //处理出现的连续0的第一个0
            {
                iCount = 1;
                for (int j = i + 1; j < sIn.Length && iValue[j] == 0 && iWeight[j] != 0; j++)
                    iCount++;
                iNext = i + iCount;            if (iWeight[i] == 0)//千万
                {
                    if (iCount != 8)
                        sb.Append("零");
                }
                else if (iWeight[i] == 7)//百万
                {
                    if (iCount < 3)
                        sb.Append("零");
                    if (iCount > 3)
                        bZeroAfterWan = true;
                }
                else if (iWeight[i] == 6)//十万
                {
                    if (iCount < 2)
                        sb.Append("零");
                    if (iCount > 2)
                        bZeroAfterWan = true;
                }
                else if (iWeight[i] != iCount)//千百十
                    sb.Append("零");
            }
        }
        return sb.ToString();
    }
      

  25.   

    都好强,给段我写的,大家一起评http://blog.csdn.net/honkerhero/archive/2007/02/02/1500684.aspx
      

  26.   

    继续改错public static string GetNumFromLeft2Right(string sIn)//fckadxz 2008 写的
    {
        long d = long.Parse(sIn);
        if (d == 0)
            return "零";
        string      sNum    = "零壹贰叁肆伍陆柒捌玖";
        string      sWeight = "仟亿拾佰仟万拾佰";
        StringBuilder sb    = new StringBuilder();
        int[]       iWeight = new int[sIn.Length];
        int[]       iValue  = new int[sIn.Length]; 
        int         iCount  = 0;
        int         iNext   = 0;
        for (int i = 0; i < sIn.Length; i++)
        {
            iWeight[i] = (sIn.Length - i) % 8;
            iValue[sIn.Length - i - 1] = (int)(d % 10);
            d = d / 10;
        }
        for (int i = 0; i < sIn.Length; i++)
        {
            if (sIn[i] > '0')
            {
                sb.Append(sNum[iValue[i]]);
                if (i < sIn.Length - 1)
                    sb.Append(sWeight[iWeight[i]]);
                iNext = i + 1;
            }
            else if (iWeight[i] == 1)
            {
                if (i < sIn.Length - 1)
                    sb.Append("亿");
                iNext = i + 1;
            }
            else if (iWeight[i] == 5)
            {
                if (i < 4 || iValue[i - 3] + iValue[i - 2] + iValue[i - 1] > 0)
                {
                    sb.Append("万");
                    if(i> iNext-5 && i<iNext -1  )
                        sb.Append("零"); 
                    else
                        iNext = i + 1;
                }
            }
            else if (i == iNext)//处理出现的连续0的第一个0
            {
                iCount = 1;
                for (int j = i + 1; j < sIn.Length && iValue[j] == 0 && iWeight[j] != 0; j++)
                    iCount++;
                iNext = i+iCount;
                if (iWeight[i] == 0)//千万
                {
                    if (iCount != 8)
                        sb.Append("零");
                }
                else if (iWeight[i] == 7)//百万
                {
                    if (iCount < 3)
                        sb.Append("零");
                }
                else if (iWeight[i] == 6)//十万
                {
                    if (iCount < 2)
                        sb.Append("零");
                }
                else if (iWeight[i] != iCount)//千百十
                    sb.Append("零");
            }
        }
        return sb.ToString();
    }
      

  27.   

    最后附上完整代码,包括了金额的处理,调用SomeStaticClass里面的GetPrice 和 GetCount方法即可.预祝大家春节快乐!    static class SomeStaticClass
        {
           //采用从左到右,直接读出的办法 fckadxz 2008
            private static string GetInt    (string sIn)
            {
                long d = long.Parse(sIn);
                if (d == 0)
                    return "零";
                string sNum = "零壹贰叁肆伍陆柒捌玖";
                string sWeight = "仟亿拾佰仟万拾佰";
                StringBuilder sb = new StringBuilder();
                int[] iWeight = new int[sIn.Length];
                int[] iValue = new int[sIn.Length];
                int iCount = 0;
                int iNext = 0;
                for (int i = 0; i < sIn.Length; i++)
                {
                    iWeight[i] = (sIn.Length - i) % 8;
                    iValue[sIn.Length - i - 1] = (int)(d % 10);
                    d = d / 10;
                }
                for (int i = 0; i < sIn.Length; i++)
                {
                    if (sIn[i] > '0')
                    {
                        sb.Append(sNum[iValue[i]]);
                        if (i < sIn.Length - 1)
                            sb.Append(sWeight[iWeight[i]]);
                        iNext = i + 1;
                    }
                    else if (iWeight[i] == 1)
                    {
                        if (i < sIn.Length - 1)
                            sb.Append("亿");
                        iNext = i + 1;
                    }
                    else if (iWeight[i] == 5)
                    {
                        if (i < 4 || iValue[i - 3] + iValue[i - 2] + iValue[i - 1] > 0)
                        {
                            sb.Append("万");
                            if (i > iNext - 5 && i < iNext - 1)
                                sb.Append("零");
                            else
                                iNext = i + 1;
                        }
                    }
                    else if (i == iNext)//处理出现的连续0的第一个0
                    {
                        iCount = 1;
                        for (int j = i + 1; j < sIn.Length && iValue[j] == 0 && iWeight[j] != 0; j++)
                            iCount++;
                        iNext = i + iCount;
                        if (iWeight[i] == 0)//千万
                        {
                            if (iCount != 8)
                                sb.Append("零");
                        }
                        else if (iWeight[i] == 7)//百万
                        {
                            if (iCount < 3)
                                sb.Append("零");
                        }
                        else if (iWeight[i] == 6)//十万
                        {
                            if (iCount < 2)
                                sb.Append("零");
                        }
                        else if (iWeight[i] != iCount)//千百十
                            sb.Append("零");
                    }
                }
                return sb.ToString();
            }
            private static string GetReal   (string sIn)
            {
                double f = double.Parse(sIn);
                if (f == 0)
                    return "";
                string sNum = "零壹贰叁肆伍陆柒捌玖";
                StringBuilder sb = new StringBuilder();
                int[] iValue = new int[sIn.Length - 2];
                for (int i = 0; i < sIn.Length - 2;i++ )
                {
                    iValue[i] = (int)((f * Math.Pow(10, i + 1)) % 10);
                }
                sb.Append("点");
                for (int i = 0; i < sIn.Length-2; i++)
                {
                    sb.Append(sNum[iValue[i]]);
                }
                return sb.ToString();
            }
            private static string GetRealPrice(string sIn)
            {
                double f = double.Parse(sIn);
                if (f == 0)
                    return "圆整";
                string sNum = "零壹贰叁肆伍陆柒捌玖";
                string sWeight = "角分";
                StringBuilder sb = new StringBuilder();
                int[] iValue = new int[2];
                for (int i = 0; i < 2; i++)
                    iValue[i] = (int)((f * Math.Pow(10, i + 1)) % 10);
                sb.Append("圆");
                sb.Append(sNum[iValue[0]]);
                if (iValue[0] > 0)
                    sb.Append(sWeight[0]);
                if (iValue[1] > 0)
                {
                    sb.Append(sNum[iValue[1]]);
                    sb.Append(sWeight[1]);
                }
                else
                {
                    sb.Append("整");
                }
                return sb.ToString();
            }
            public  static string GetCount  (string sIn)
            {
                decimal f = decimal.Parse(sIn);
                long d = (long)f;
                decimal f2 = f - d;
                return GetInt(d.ToString ())+ GetReal(f2.ToString ());;
            }
            public  static string GetPrice  ( string sIn)
            {
                decimal f = decimal.Parse(sIn);
                long d = (long)f;
                decimal f2 = f - d;
                return GetInt(d.ToString()) + GetRealPrice(f2.ToString("f2")); ;
            }
        }
      

  28.   

      f2.ToString("f2")的目的是四舍五入吧,万一入到整数位怎么办,出错了吧,你改成 string sIn = "1.995"; 看看输出什么东西。
      你这用 long 拼起来的程序是很失败的,虽然貌似速度很快,可是毫无设计思想可言,在此基础上很难扩充,达到微软那种功能,例如多国货币规格的支持,(国内兆为一亿亿,日韩兆为一万亿),更别提decimal数字支持。能实现也是一身补丁。
      而且你引以为豪的速度并没有快过微软的程序,只是你投机取巧用 long 数据比 decimal 小的特点造成的假象,我把微软的源码核心提取出来,改成long版本的,给你看看什么叫优秀的程序,因为要兼容你的参数设定,效率和安全性都完了,不过还是比你楼上的垃圾代码快很多。
      

  29.   

    using System.Collections.Generic;
    using System;
    using System.Globalization;
    using System.Diagnostics;
    using System.Text.RegularExpressions;
    using System.Text;class Program
    {
        static void Main(string[] args)
        {
            DateTime dt1 = DateTime.Now;
            string s1 = "";
            string s2 = "";
            Stack<char> s3=new Stack<char>(0) ;
            string sIn = "1001001000001";
            //string sIn = "1.995";
            decimal d = decimal.MaxValue;
            int iCount = 100000;        DateTime dt2 = DateTime.Now;
            for (int i = 0; i < iCount; i++)
            {
                s2 = SomeStaticClass.GetPrice(sIn);
            }
            TimeSpan ts2 = DateTime.Now - dt2; ;
            System.Console.WriteLine("fckadxz   写的:" + s2 + "   calcu   " + iCount.ToString() + "times   elapsed   " + ts2.TotalMilliseconds.ToString() + "ms");        DateTime dt3 = DateTime.Now;
            for (int i = 0; i < iCount; i++)
            {
                s3 = RMB.DecimalFormatter(sIn);
            }
            TimeSpan ts3 = DateTime.Now - dt3; ;
            System.Console.WriteLine("microsoft   写的:" + new string(s3.ToArray()) + "   calcu   " + iCount.ToString() + "times   elapsed   " + ts3.TotalMilliseconds.ToString() + "ms");
            Console.ReadKey();
        }
    }
      

  30.   

    static class SomeStaticClass
    {
        //采用从左到右,直接读出的办法 fckadxz 2008
        private static string GetInt(string sIn)
        {
            long d = long.Parse(sIn);
            if (d == 0)
                return "零";
            string sNum = "零壹贰叁肆伍陆柒捌玖";
            string sWeight = "仟亿拾佰仟万拾佰";
            StringBuilder sb = new StringBuilder();
            int[] iWeight = new int[sIn.Length];
            int[] iValue = new int[sIn.Length];
            int iCount = 0;
            int iNext = 0;
            for (int i = 0; i < sIn.Length; i++)
            {
                iWeight[i] = (sIn.Length - i) % 8;
                iValue[sIn.Length - i - 1] = (int)(d % 10);
                d = d / 10;
            }
            for (int i = 0; i < sIn.Length; i++)
            {
                if (sIn[i] > '0')
                {
                    sb.Append(sNum[iValue[i]]);
                    if (i < sIn.Length - 1)
                        sb.Append(sWeight[iWeight[i]]);
                    iNext = i + 1;
                }
                else if (iWeight[i] == 1)
                {
                    if (i < sIn.Length - 1)
                        sb.Append("亿");
                    iNext = i + 1;
                }
                else if (iWeight[i] == 5)
                {
                    if (i < 4 || iValue[i - 3] + iValue[i - 2] + iValue[i - 1] > 0)
                    {
                        sb.Append("万");
                        if (i > iNext - 5 && i < iNext - 1)
                            sb.Append("零");
                        else
                            iNext = i + 1;
                    }
                }
                else if (i == iNext)//处理出现的连续0的第一个0
                {
                    iCount = 1;
                    for (int j = i + 1; j < sIn.Length && iValue[j] == 0 && iWeight[j] != 0; j++)
                        iCount++;
                    iNext = i + iCount;
                    if (iWeight[i] == 0)//千万
                    {
                        if (iCount != 8)
                            sb.Append("零");
                    }
                    else if (iWeight[i] == 7)//百万
                    {
                        if (iCount < 3)
                            sb.Append("零");
                    }
                    else if (iWeight[i] == 6)//十万
                    {
                        if (iCount < 2)
                            sb.Append("零");
                    }
                    else if (iWeight[i] != iCount)//千百十
                        sb.Append("零");
                }
            }
            return sb.ToString();
        }
        private static string GetReal(string sIn)
        {
            double f = double.Parse(sIn);
            if (f == 0)
                return "";
            string sNum = "零壹贰叁肆伍陆柒捌玖";
            StringBuilder sb = new StringBuilder();
            int[] iValue = new int[sIn.Length - 2];
            for (int i = 0; i < sIn.Length - 2; i++)
            {
                iValue[i] = (int)((f * Math.Pow(10, i + 1)) % 10);
            }
            sb.Append("点");
            for (int i = 0; i < sIn.Length - 2; i++)
            {
                sb.Append(sNum[iValue[i]]);
            }
            return sb.ToString();
        }
        private static string GetRealPrice(string sIn)
        {
            double f = double.Parse(sIn);
            if (f == 0)
                return "圆整";
            string sNum = "零壹贰叁肆伍陆柒捌玖";
            string sWeight = "角分";
            StringBuilder sb = new StringBuilder();
            int[] iValue = new int[2];
            for (int i = 0; i < 2; i++)
                iValue[i] = (int)((f * Math.Pow(10, i + 1)) % 10);
            sb.Append("圆");
            sb.Append(sNum[iValue[0]]);
            if (iValue[0] > 0)
                sb.Append(sWeight[0]);
            if (iValue[1] > 0)
            {
                sb.Append(sNum[iValue[1]]);
                sb.Append(sWeight[1]);
            }
            else
            {
                sb.Append("整");
            }
            return sb.ToString();
        }
        public static string GetCount(string sIn)
        {
            decimal f = decimal.Parse(sIn);
            long d = (long)f;
            decimal f2 = f - d;
            return GetInt(d.ToString()) + GetReal(f2.ToString()); ;
        }
        public static string GetPrice(string sIn)
        {
            decimal f = decimal.Parse(sIn);
            long d = (long)f;
            decimal f2 = f - d;
            return GetInt(d.ToString()) + GetRealPrice(f2.ToString("f2")); ;
        }
    }static class RMB
    {
        private static readonly string DigitText = "零壹贰叁肆伍陆柒捌玖";
        private static readonly string PositionText = "圆拾佰仟萬億兆京垓秭穰";
        private static readonly string OtherText = "分角整负";    private static void GetFractionStack(int num, Stack<char> stack)
        {
            int fen, jiao = Math.DivRem(num, 10, out fen);
            if (fen != 0)
            {
                stack.Push(OtherText[0]);
                stack.Push(DigitText[fen]);
            }
            if (jiao != 0)
            {
                stack.Push(OtherText[1]);
                stack.Push(DigitText[jiao]);
            }
        }
        private static void GetIntegerStack(long num, int position, Stack<char> stack)
        {
            if (num < 10000L)
            {
                int _num = (int)num;
                for (int i = 0, mod_10 = 0; i < 4; i++)
                {
                    bool behindZero = mod_10 == 0;
                    _num = Math.DivRem(_num, 10, out mod_10);
                    if (mod_10 == 0)
                    {
                        if (behindZero)
                            if (_num == 0)
                                break;
                            else
                                continue;
                    }
                    else if (i > 0)
                        stack.Push(PositionText[i]);
                    stack.Push(DigitText[mod_10]);
                }
            }
            else
            {
                GetIntegerStack(num % 10000L, position, stack);
                int mask = -1, offset = 4;
                while ((position & (0x1 << ++mask)) == 0) ;
                mask += offset;
                while (stack.Peek() == PositionText[offset++])
                    stack.Pop();
                stack.Push(PositionText[mask]);
                GetIntegerStack(num / 10000L, position + 1, stack);
            }
        }
        public static Stack<char> DecimalFormatter(string input)
        {
            decimal d = decimal.Parse(input) + 0.005M;
            bool isNegate = input[0] == '-';
            long integer = decimal.ToInt64(d);
            int fraction = decimal.ToInt32((d - integer) * 100M);
            Stack<char> stack = new Stack<char>(60);
            if (fraction == 0)
                stack.Push(OtherText[2]);
            else
                GetFractionStack(fraction, stack);
            if (integer != 0L)
            {
                stack.Push(PositionText[0]);
                GetIntegerStack(integer, 1, stack);
                if (stack.Peek() == DigitText[0])
                    stack.Pop();
            }
            else if (fraction == 0)
            {
                stack.Push(PositionText[0]);
                stack.Push(DigitText[0]);
            }
            if (isNegate)
                stack.Push(OtherText[3]);
            return stack;
        }
    }
    // "1.995";
    //fckadxz   写的:壹圆零整   calcu   100000times   elapsed   1271.8288ms
    //microsoft   写的:贰圆整   calcu   100000times   elapsed   450.648ms
    // "1001001000001"
    //fckadxz   写的:壹万零壹拾亿零壹佰万零壹圆整   calcu   100000times   elapsed   1582.2752ms
    //microsoft   写的:壹萬零壹拾億零壹佰萬零壹圆整   calcu   100000times   elapsed 801.152ms
      

  31.   

    好了,结贴了.就当抛砖引玉.看来我引以为豪的东西的只能叫砖头了.微软的算法和 IV空间 的有些类似.谢谢大家.
    感谢  IV空间\我为编程狂还有其他网友 的积极参与.使我从中学到了不少.
      

  32.   

    发现了点问题, 我为编程狂 把 new   string(s3.ToArray())    这个写在时间测试区外,而 s3并不是合乎要求的字符串结果,所以,这个测试不公平.如果把这句代码放入 时间测试区,则差别并不是很大,400:500的样子.
    color=#0000FF]最精简的代码和最快的代码都是我写的[/color]
    这是你的代码吗?有没有知识产权的概念?反编译的代码是不能随便用的,有时还是违法的.
    不尊重别人的劳动成果,毛主席说过,是要不得的.
      

  33.   

    知识产权吗?
    发表于:2008-01-28 06:10:3035楼 得分:0 
    这个代码的字符串操作借鉴了   空间IV   的,但是整体算法完全不同.又把效率提高了一大截. 
    你这不是也在“借鉴”。  下面这段就是我说的微软的源码,和我的代码差别非常大吧。我也只是“借鉴”了递归架构,其他代码都是我自己写出来的。不信你可以把下面这段代码和我写的比较一下,假如你能看得懂我的代码的话。http://topic.csdn.net/u/20080125/09/04c65875-4f50-42cd-bd63-d7b1429e42e1.html 53楼
      你说返回值要转成字符串比较才公平,谁说的?我还觉得大家都返回 Stack 集合或字符数组测试速度才公平。
      微软的程序向来层次分明。核心算法返回数组或集合形式的,界面层算法才转用户需要的字符串,这样便于日后程序的功能扩充和维护,例如用户可能需要“整”,可能不需要。这就可以在界面层操作而非核心层。
      如果是你一定在核心算法里增加 if 语句,把核心算法搞成补丁铺。像你那种不分层的浑然一体的结构,最后只能落得个全身补丁的下场。我倒是想把你的返回值改成比较优势的数组形式,可惜那样你得程序就变得更慢了。
      另外返回字符集合而非字符串给界面层的好处是显而易见的,操作字符串带来的系统消耗比操作数组大的多,你可能理解不了,不过你改了我的返回值为字符串后速度明显下降,应该能明白这种消耗吧。
      假如微软雇佣我们俩单独完成整个 EastAsiaNumericFormatter ,你的程序如果不分层,肯定满是补丁,维护困难。如果分层,在各层间用字符串传递,效率受很大影响,最终只能落后于我。况且我写的就是转字符串也快过你的,更别提你难以解决的跨小数点四舍五入错误和万亿以上的单位错误。还有 Console 可以直接输出 Char[],为了照顾你得阅读习惯,我才转成 string 形式。protected virtual void GetIntegralStack(decimal num, ulong position, StackWithIndex stack)
    {
        if (num < 10000M)
        {
            if ((num != 0M) || (position == 0xe8d4a51000L))
            {
                stack.Push(this.GetPositionText(position));
            }
            for (int i = 0; i < 4; i++)
            {
                int digit = (int) decimal.op_Modulus(num, 10M);
                ulong num4 = (ulong) Math.Pow(10.0, (double) i);
                num /= 10M;
                stack.Push(this.GetDigitText(digit, num4));
            }
        }
        else
        {
            this.GetIntegralStack(Math.Truncate(decimal.op_Modulus(num, 10000M)), position, stack);
            this.GetIntegralStack(Math.Truncate((decimal) (num / 10000M)), position * ((ulong) 0x2710L), stack);
        }

      

  34.   

    最后 加 一个 极速无限精度版,可以转换1000位以上的 2位小数数字字符串,速度也还可以.有个缺点是没有在里面处理四舍五入.using System;
    using System.Collections.Generic;
    using System.Text;
    namespace 大写5
    {
        class Program
        {
            static void Main(string[] args)
            {
                Stack<char> stack = new Stack<char>();
                string sIn = "12222000000000000000000001.34";
                int iCount = 100000;
                DateTime dt2 = DateTime.Now;
                for (int i = 0; i < iCount; i++)
                {
                    stack = SomeStaticClass.GetPrice2(sIn);
                }
                TimeSpan ts2 = DateTime.Now - dt2; ;
                System.Console.WriteLine("fckadxz 2008 无限版:" + new string(stack.ToArray()) + "       calcu       " + iCount.ToString() + "times       elapsed       " + ts2.TotalMilliseconds.ToString() + "ms");            Console.ReadKey();
            }
        }
        static class SomeStaticClass
        {
            private static Dictionary<char, char> dn = new Dictionary<char, char>();
            static SomeStaticClass()
            {
                dn.Add('1', '壹');
                dn.Add('2', '贰');
                dn.Add('3', '叁');
                dn.Add('4', '肆');
                dn.Add('5', '伍');
                dn.Add('6', '陆');
                dn.Add('7', '柒');
                dn.Add('8', '捌');
                dn.Add('9', '玖');
                dn.Add('0', '零');
            }
            private static readonly string sNumFenJiaoYuan = "分角圆整";
            private static readonly string sNum = "零壹贰叁肆伍陆柒捌玖";
            private static readonly char cZero = '零';
            private static readonly char cWan = '万';
            private static readonly char cYi = '亿';
            private static readonly string sWeight = "仟亿拾佰仟万拾佰";
            //fckadxz   2008 精度无限制版(甚至1000万位!),你可以 这样调用 
            //SomeStaticClass.GetPrice2("10000000000000000000000000000000000000000001.23")
            internal static Stack<char> GetPrice2(string sIn)//使用 xxxxx.xx的格参数格式 x范围0-9
            {
                Stack<char> chStack = new Stack<char>();
                int iLen = sIn.Length - 3;
                int iError = -1;
                int iZero = 0;
                int iZeroAll = 0;
                //检查数据
                for (int i = 0; i < sIn.Length; i++)
                {
                    if (i == iLen)
                    {
                        if (sIn[i] != '.')
                        {
                            iError = i + 1;
                            break;
                        }
                    }
                    else if (sIn[i] < '0' || sIn[i] > '9')
                    {
                        iError = i + 1;
                        break;
                    }
                }
                if (iError >= 0)
                    throw new Exception("数据错误出现在 \r\n" + sIn + " \r\n第" + iError + "位置!");
                //分
                char c = sIn[sIn.Length - 1];
                if (c == '0')
                {
                    chStack.Push(sNumFenJiaoYuan[3]);
                    iZero++;
                }
                else
                {
                    chStack.Push(sNumFenJiaoYuan[0]);
                    chStack.Push(dn[c]);
                }
                //角
                c = sIn[sIn.Length - 2];
                if (c == '0')
                {
                    if (iZero == 0)
                        chStack.Push(dn[c]);
                }
                else
                {
                    chStack.Push(sNumFenJiaoYuan[1]);
                    chStack.Push(dn[c]);
                }
                //整数部分
                iZero = 0;            chStack.Push(sNumFenJiaoYuan[2]);
                int iw = 1;
                for (int i = iLen - 1; i >= 0; i--, iw++)
                {
                    if (iw == 8)
                        iw = 0;
                    c = sIn[i];
                    if (c > '0')
                    {
                        if (iZero > 0)
                        {
                            if (iw == 1)//亿
                            {
                                if (iZero != 8)
                                    chStack.Push(cZero);
                            }
                            else if (iw == 2)//十
                            {                        }
                            else if (iw == 3)//百
                            {
                                if (iZero < 2)
                                    chStack.Push(cZero);
                            }
                            else if (iw == 4)//千
                            {
                                if (iZero < 3)
                                    chStack.Push(cZero);
                            }
                            else if (iw == 5)//万
                            {
                                if (iZero < 4)
                                    chStack.Push(cZero);
                            }
                            else if (iw == 6)//十万
                            {
                                if (iZero != 5 && iZero != 1)
                                    chStack.Push(cZero);
                                chStack.Push(cWan);
                            }
                            else if (iw == 7)//百万
                            {
                                if (iZero == 2)
                                {
                                    chStack.Push(cWan);
                                }
                                else if (iZero > 2)
                                {
                                    if (iZero != 6)
                                        chStack.Push(cZero);
                                    chStack.Push(cWan);                            }
                                else
                                {
                                    chStack.Push(cZero);
                                }
                            }
                            else if (iw == 0)//千万
                            {
                                if (iZero == 3)
                                {
                                    chStack.Push(cWan);
                                }
                                else if (iZero > 3)
                                {
                                    if (iZero != 7)
                                        chStack.Push(cZero);
                                    chStack.Push(cWan);
                                }
                                else
                                {
                                    chStack.Push(cZero);
                                }
                            }
                        }
                        iZero = 0;
                        if (i < iLen - 1)
                            chStack.Push(sWeight[iw]);
                        chStack.Push(dn[c]);
                    }
                    else
                    {
                        if (iw == 1)//亿和个位
                        {                        if (i < iLen - 1)
                            {
                                if (iZero < 8)
                                    chStack.Push(cZero);
                                chStack.Push(cYi);
                            }
                            iZero = 1;
                        }
                        else
                            iZero++;
                        iZeroAll++;
                    }
                }
                if (iZeroAll == iLen)
                    chStack.Push(cZero);
                return chStack;
            }
        } 
    }
      

  35.   

    呵呵... 再位真可爱... 不如你们再比比RMB大写转小写的... 看看谁的程序更快... ^o^
      

  36.   

    你还在我的帖子说四舍五入可以用 Math.Round 方法,我可以明确地告诉你那会出错。你运行一下就明白了。[code=C#]using System;
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Math.Round(1.5));
            Console.WriteLine(Math.Round(2.5));
            Console.WriteLine(string.Format("{0:F0}", 1.5));
            Console.WriteLine(string.Format("{0:F0}", 2.5));
        }
    }[code]真是的,浪费我时间给你上课,交学费昂
    Round 方法默认行为:当一个数字是其他两个数字的中间值时,会将其舍入为最接近的偶数。  
      

  37.   

    单纯拼速度的话,我知道一种最快的方法,不过自认为是程序员的话,就不应该采用那种的方法。
     decimal 也不过 28 位,可以对应每一位写几句处理代码,从右往左顺序处理下来,没有循环,没有嵌套,没有回溯操作,那样最快。
      

  38.   

    RMB 大写转小写谁用?反正我没看有人用过。也不是写不出来,不过写来做啥?而且像楼主这种亿亿亿单位拿去反向转换可能会出错,除非楼主给人家再开发个补丁程序。
      

  39.   

    MidpointRounding.AwayFromZero 都能叫四舍五入?还可以?你没搞错吧
      

  40.   


    [align=center]第一部分 会计基本知识与基本技能一、汉字书写和会计大写数字[/align]4.特别是注意练好表示数额多少的那些汉字,尽可能的达到合乎标准写法且书写特别流
    利。一般讲,财会工作中除运用阿拉伯字书写数额外,不少地方需要用汉字来表示金额,如,书写借条时,不仅要看清阿拉伯字数额(小写),而且要运用汉字书写金额(大写),两者缺一不可。从一般情况看,书写金额的汉字应使用会计体汉字,即:零壹贰叁肆伍陆柒捌玖拾佰仟万亿大写数字,不应使用“另(或令)、一、二、三、四、五、六、七、八、九、十、百、千”等汉字;更不能用谐音字替代会计体数字。非经国务院公布的简体字及地方约定俗成的不规范汉字,理应不要会计记录中出现。除此之外,在行文中表示数额的同一行相邻数字之间,最好要空出半个汉字大写的位置,以示区别。汉字数码标准字体如下:
          零  壹  贰  叁  肆  伍  陆  柒  捌  玖  拾  佰  仟  万  亿看来国务院好像没公布“兆”等字,那个“等”的意思看来国务院还没给出来。所以你说亿亿是对的,冤枉你了,不好意思。
      

  41.   

    不过你 56 楼的程序那么多 if,应该用 switch 才会更快。用 if 也应该用二分法查找。
      

  42.   

    fckadxz 2008 无限版:零圆零壹分
    fckadxz 2008 无限版:零圆壹角整
    这怎么看着这么别扭
      

  43.   

    MidpointRounding.AwayFromZero 对付正数的四舍五入,应该没问题.负数据说不行.像这样: double f = Math.Round(123.456,2,MidpointRounding.AwayFromZero);网上也搜了下,有个家伙也这样说.他还说msdn上关于MidpointRounding.AwayFromZero 的解释是错的.反正msdn上的东西,例子可以看,叙述看起来往往很费事.关于if和switch,我写的时候闪了下switch,还是没有用.代码写的有点潦草,当时赶着要去吃饭.关于二分法:有时间多探讨这方面的算法问题.以前写过一些数据库连接算法(join 算法).程序中的判断是应该越少越好.特别是那种消耗大的判断.
      

  44.   

    MidpointRounding.AwayFromZero 原来是这个意思,我也不知道,汗自己一个。
      

  45.   

    我觉得从实际使用方式来看,用户提供的参数应该会是 decimal 或 double,而非字符串形式。况且字符串什么情况都有,要检查字符串的错误也是一种负担。所以应该回头继续研究 decimal 才对。double 可以使处理速度加快一倍,但会损失精度,不提倡,而 long 也可以使处理速度加快一倍,但需要拆解小数部分,特别是四舍五入影响到整数的时候,处理也挺麻烦,且用户提供decimal 大数时还是无法转换。所以应该用 decimal。而我照微软架构改的那个也有不足,来回传递值类型的 decimal结构对系统的消耗相当大,我曾经试过用Int32,速度提到了4倍多。不过最后因为单位不好处理没写出来。我那个还有个缺点,或者说没完成的功能,就是通过一个参数让用户选择单位的类型,即上法、中法、下法和你说的亿亿切换。那个架构应该能实现,只不过我没做出来。你要是继续研究下去,应该关注这些,我觉得。
      

  46.   


    using System;
    using System.Collections.Generic;
    namespace 大写5
    {
        class Program
        {
            static void Main(string[] args)
            {
                Stack <char> stack = new Stack<char>();
                string sIn = "999000999.45";
                int iCount = 100000;
                DateTime dt2 = DateTime.Now;
                for (int i = 0; i < iCount; i++)
                {
                    stack = SomeStaticClass.GetPrice2(sIn);
                }
                TimeSpan ts2 = DateTime.Now - dt2; ;
                Console.WriteLine("fckadxz 2008 无限版:");
                Console.WriteLine(sIn);
                Console.WriteLine(new string(stack.ToArray()));
                Console.WriteLine("trans "+iCount+ " times,elapsed " + ts2.TotalMilliseconds.ToString() + " ms");
                Console.ReadKey();
            }
        }
        static class SomeStaticClass
        {
            private static Dictionary<char, char> dn = new Dictionary<char, char>();
            static SomeStaticClass()
            {
                dn.Add('1', '壹');
                dn.Add('2', '贰');
                dn.Add('3', '叁');
                dn.Add('4', '肆');
                dn.Add('5', '伍');
                dn.Add('6', '陆');
                dn.Add('7', '柒');
                dn.Add('8', '捌');
                dn.Add('9', '玖');
                dn.Add('0', '零');
            }
            private static readonly string sNumFenJiaoYuan = "分角圆整";
            private static readonly char cZero = '零';
            private static readonly char cWan = '万';
            private static readonly char cYi = '亿';
            private static readonly string sWeight = "仟亿拾佰仟万拾佰";
            //fckadxz   2008 精度无限制版(甚至1000万位!),你可以 这样调用 
            //SomeStaticClass.GetPrice2("100000001.23")
            //使用 m.xx的格参数格式 m:>=0的整数, x范围0-9,小数点左边大于等于1位,小数点右刚好2位
            internal static Stack<char> GetPrice2(string sIn)
            {
                Stack<char> chStack = new Stack<char>();
                int iLen = sIn.Length - 3;
                int iZero = 0;
                string strErrow = "";
                bool bZeroYuan = false;
                bool bZeroJiao = false;
                bool bZeroFen= false;            if (sIn.Length < 4)
                    strErrow = "输入数据不对!输入字符串至少4个字符(小数点左1位,小数点1位,小数右2位).";
                //检查数据
                for (int i = 0; i < sIn.Length && strErrow .Length == 0; i++)
                {
                    if(i==0 && iLen >1)
                    {
                        if(sIn[i] < '1' || sIn[i] > '9')
                            strErrow = "左起第1位字符错误,该字符是"+sIn [i];
                    }
                    else if (i == iLen)
                    {
                        if (sIn[i] != '.')
                            strErrow = "左起第" + (i + 1) + "位字符错误,该字符是 '" + sIn[i]+"',此位应该是小数点";
                    }
                    else if (sIn[i] < '0' || sIn[i] > '9')
                    {
                        strErrow = "左起第" + (i + 1) + "位字符错误,该字符是" + sIn[i];
                    }
                }
                if (strErrow .Length>0)
                    throw new Exception("\r\n"+strErrow );
                if (iLen == 1)
                {
                    bZeroYuan = sIn[0] == '0';
                    bZeroJiao  = sIn[2] == '0';
                    bZeroFen = sIn[3] == '0';
                    if (bZeroYuan && bZeroJiao && bZeroFen)//零元整
                    {
                        chStack.Push(sNumFenJiaoYuan[3]);
                        chStack.Push(sNumFenJiaoYuan[2]);
                        chStack.Push(cZero);
                        return chStack;
                    }
                }
                //分
                char c = sIn[sIn.Length - 1];
                if (c == '0')
                {
                    chStack.Push(sNumFenJiaoYuan[3]);
                    iZero++;
                }
                else
                {
                    chStack.Push(sNumFenJiaoYuan[0]);
                    chStack.Push(dn[c]);
                }
                //角
                c = sIn[sIn.Length - 2];
                if (c == '0')
                {
                    if (iZero == 0 && bZeroYuan == false )
                        chStack.Push(cZero);
                }
                else
                {
                    chStack.Push(sNumFenJiaoYuan[1]);
                    chStack.Push(dn[c]);
                }
                if (bZeroYuan == true)
                    return chStack;            //整数部分
                iZero = 0;
                chStack.Push(sNumFenJiaoYuan[2]);
                int iw = 1;
                for (int i = iLen - 1; i >= 0; i--, iw++)
                {
                    if (iw == 8)
                        iw = 0;
                    c = sIn[i];
                    if (c > '0')
                    {
                        if (iZero > 0)
                        {
                            switch (iw)
                            {
                            case 1://亿
                                if (iZero != 8)
                                    chStack.Push(cZero);
                                break ;
                            case 2://十
                                break ;
                            case  3://百
                                if (iZero < 2)
                                    chStack.Push(cZero);
                                break;
                            case  4://千
                                if (iZero < 3)
                                    chStack.Push(cZero);
                                break;
                            case  5://万
                                if (iZero < 4)
                                    chStack.Push(cZero);
                                break;
                            case  6://十万
                                if (iZero != 5 && iZero != 1)
                                    chStack.Push(cZero);
                                chStack.Push(cWan);
                                break;
                           case  7://百万
                                if (iZero == 2)
                                {
                                    chStack.Push(cWan);
                                }
                                else if (iZero > 2)
                                {
                                    if (iZero != 6)
                                        chStack.Push(cZero);
                                    chStack.Push(cWan);                            }
                                else
                                {
                                    chStack.Push(cZero);
                                }
                                break;
                            case 0://千万
                                if (iZero == 3)
                                {
                                    chStack.Push(cWan);
                                }
                                else if (iZero > 3)
                                {
                                    if (iZero != 7)
                                        chStack.Push(cZero);
                                    chStack.Push(cWan);
                                }
                                else
                                {
                                    chStack.Push(cZero);
                                }
                                break;
                            }
                        }
                        iZero = 0;
                        if (i < iLen - 1)
                            chStack.Push(sWeight[iw]);//因为不是0且不是个位 有权
                        chStack.Push(dn[c]);//因为不是0 有数字
                    }
                    else
                    {
                        if (iw == 1)//亿和个位
                        {
                            if (i < iLen - 1)
                            {
                                if (iZero < 8)
                                    chStack.Push(cZero);
                                chStack.Push(cYi);
                            }
                            iZero = 1;
                        }
                        else
                            iZero++;
                    }
                }
                return chStack;
            }
        } 
    }
      

  47.   

    上面是修改后的代码.修正了 数据检查 部分和 0.00,0.01,0.12这类数据的转换问题.
    对于参数问题,我的看法是,这个算法本来基于字符串,就效率和适应性来讲,都好于object的装拆箱.数据检查不是问题.春节到了,将和csdn上的弟兄们分别一段日子了,祝大家春节好!
      

  48.   

    你还真是个认真的人,参数用string也好。
    微软那个就是object拆箱的,还多了很多检查,最后才转decimal开始计算,大概为了兼容多种类型的那个格式化接口的需要。