在金额转换时,要求数字和单位转为繁体的.浮点数的话读到小数点后两位,也就是分.
将数字转为繁体的没什么问题,主要是加上单位要考虑的特殊情况,比如1000不能读成1千零零零圆;1010要读成1千零一拾圆;小数点前面是0的就只读角和分...
  主要用到数组,还有substring
哪位有没有好的算法可以实现.可以用C#,也可以用ASP.NET

解决方案 »

  1.   

    这个怎么样?
    public string ToUpperMoney(decimal d)
    {
    if (d == 0)
    return "零元整";

    string je = d.ToString("####.00");
    if (je.Length > 15)
    return "";
    je = new String('0',15 - je.Length) + je; //若小于15位长,前面补0 string stry = je.Substring(0,4); //取得'亿'单元
    string strw = je.Substring(4,4); //取得'万'单元
    string strg = je.Substring(8,4); //取得'元'单元
    string strf = je.Substring(13,2); //取得小数部分

    string str1 = "",str2 = "",str3 = ""; str1 = this.getupper(stry,"亿"); //亿单元的大写
    str2 = this.getupper(strw,"万"); //万单元的大写
    str3 = this.getupper(strg,"元"); //元单元的大写
    string str_y = "", str_w = "";
    if (je[3] == '0' || je[4] == '0') //亿和万之间是否有0
    str_y = "零";
    if (je[7] == '0' || je[8] == '0') //万和元之间是否有0
    str_w = "零"; string ret = str1 + str_y + str2 + str_w + str3; //亿,万,元的三个大写合并 for (int i = 0 ;i < ret.Length;i++) //去掉前面的"零"
    {
    if (ret[i] != '零')
    {
    ret = ret.Substring(i);
    break;
    } }
    for (int i = ret.Length - 1;i > -1 ;i--) //去掉最后的"零"
    {
    if (ret[i] != '零')
    {
    ret = ret.Substring(0,i+1);
    break;
    }
    }

    if (ret[ret.Length  - 1] != '元') //若最后不位不是'元',则加一个'元'字
    ret = ret + "元"; if (ret == "零零元") //若为零元,则去掉"元数",结果只要小数部分
    ret = "";

    if (strf == "00") //下面是小数部分的转换
    {
    ret = ret + "整";
    }
    else
    {
    string tmp = "";
    tmp = this.getint(strf[0]);
    if (tmp == "零")
    ret = ret + tmp;
    else
    ret = ret + tmp + "角"; tmp = this.getint(strf[1]);
    if (tmp == "零")
    ret = ret + "整";
    else
    ret = ret + tmp + "分";
    } if (ret[0] == '零')
    {
    ret = ret.Substring(1); //防止0.03转为"零叁分",而直接转为"叁分"
    } return  ret; //完成,返回
    } public string ToUpperDigit(decimal d)
    {
    if (d == 0)
    return "";

    string je = d.ToString("####.00");
    if (je.Length > 15)
    return "";
    je = new String('0',15 - je.Length) + je; //若小于15位长,前面补0 string stry = je.Substring(0,4); //取得'亿'单元
    string strw = je.Substring(4,4); //取得'万'单元
    string strg = je.Substring(8,4); //取得'元'单元
    string strf = je.Substring(13,2); //取得小数部分

    string str1 = "",str2 = "",str3 = ""; str1 = this.getupper(stry,"亿"); //亿单元的大写
    str2 = this.getupper(strw,"万");                     //万单元的大写
    if(System.Convert.ToInt32(strf)!=0)
    {
    str3 = this.getupper(strg,"点"); //元单元的大写
    }
    else 
    {
    str3=this.getupper(strg,"");
    }
    string str_y = "", str_w = "";
    if (je[3] == '0' || je[4] == '0') //亿和万之间是否有0
    str_y = "零";
    if (je[7] == '0' || je[8] == '0') //万和元之间是否有0
    str_w = "零"; string ret = str1 + str_y + str2 + str_w + str3; //亿,万,元的三个大写合并 for (int i = 0 ;i < ret.Length;i++) //去掉前面的"零"
    {
    if (ret[i] != '零')
    {
    ret = ret.Substring(i);
    break;
    } }
    for (int i = ret.Length - 1;i > -1 ;i--) //去掉最后的"零"
    {
    if (ret[i] != '零')
    {
    ret = ret.Substring(0,i+1);
    break;
    }
    }

    // if (ret[ret.Length  - 1] != '') //若最后不位不是'元',则加一个'元'字
    // ret = ret + ""; if (ret == "零零") //若为零元,则去掉"元数",结果只要小数部分
    ret = "零点";

    if (strf == "00") //下面是小数部分的转换
    {
    ret = ret + "";
    }
    else
    {
    string tmp = "";
    tmp = this.getint(strf[0]);
    if (tmp == "零")
    ret = ret + tmp;
    else
    ret = ret + tmp + ""; tmp = this.getint(strf[1]);
    if (tmp == "零")
    ret = ret + "";
    else
    ret = ret + tmp + "";
    } //if (ret[0] == '零')
    // {
    // ret = ret.Substring(1); //防止0.03转为"零叁分",而直接转为"叁分"
    // } return  ret; //完成,返回
    }
    /// <summary>
    /// 把一个单元转为大写,如亿单元,万单元,个单元
    /// </summary>
    /// <param name="str">这个单元的小写数字(4位长,若不足,则前面补零)</param>
    /// <param name="strDW">亿,万,元</param>
    /// <returns>转换结果</returns>
    private string getupper(string str,string strDW)
    {
    if (str == "0000")
    return ""; string ret = "";
    string tmp1 = this.getint(str[0]) ;
    string tmp2 = this.getint(str[1]) ;
    string tmp3 = this.getint(str[2]) ;
    string tmp4 = this.getint(str[3]) ;
    if (tmp1 != "零")
    {
    ret = ret + tmp1 + "仟";
    }
    else
    {
    ret = ret + tmp1;
    } if (tmp2 != "零")
    {
    ret = ret + tmp2 + "佰";
    }
    else
    {
    if (tmp1 != "零") //保证若有两个零'00',结果只有一个零,下同
    ret = ret + tmp2;
    } if (tmp3 != "零")
    {
    ret = ret + tmp3 + "拾";
    }
    else
    {
    if (tmp2 != "零")
    ret = ret + tmp3;
    } if (tmp4 != "零")
    {
    ret = ret + tmp4 ;
    }

    if (ret[0] == '零') //若第一个字符是'零',则去掉
    ret = ret.Substring(1);
    if (ret[ret.Length - 1] == '零') //若最后一个字符是'零',则去掉
    ret = ret.Substring(0,ret.Length - 1); return ret + strDW; //加上本单元的单位

    }
    /// <summary>
    /// 单个数字转为大写
    /// </summary>
    /// <param name="c">小写阿拉伯数字 0---9</param>
    /// <returns>大写数字</returns>
    private string getint(char c)
    {
    string str = "";
    switch ( c )
    {
    case '0':
    str = "零";
    break;
    case '1':
    str = "壹";
    break;
    case '2':
    str = "贰";
    break;
    case '3':
    str = "叁";
    break;
    case '4':
    str = "肆";
    break;
    case '5':
    str = "伍";
    break;
    case '6':
    str = "陆";
    break;
    case '7':
    str = "柒";
    break;
    case '8':
    str = "拐";
    break;
    case '9':
    str = "玖";
    break;
    }
    return str;
    }
      

  2.   

    在转为繁体时我也用的是switch case
      主要是判断语句比较复杂,有些情况不知道怎么处理
      

  3.   

    public class NumProcess
    {
    #region 数值大写
    private const string Num1 = "壹";
    private const string Num2 = "贰";
    private const string Num3 = "叁";
    private const string Num4 = "肆";
    private const string Num5 = "伍";
    private const string Num6 = "陆";
    private const string Num7 = "柒";
    private const string Num8 = "捌";
    private const string Num9 = "玖";
    private const string Num0 = "零"; private const string NumShi = "拾";
    private const string NumBai = "佰";
    private const string NumQian = "仟";
    private const string NumWan = "萬";
    private const string NumYi = "亿"; private const string Zheng = "整";
    private const string Yuan = "元";
    private const string Jiao = "角";
    private const string Fen = "分"; #endregion

    /// <summary>
    /// 根据数字生成相应的大写型字符串
    /// </summary>
    public static string GenerateDaXieNum( decimal dec )
    {
    try
    {
    string sign = "";
    if ( dec < 0 )
    {
    sign = "负";
    dec = 0 - dec;
    } long lng = Convert.ToInt64( dec );
    if ( lng > dec )
    lng --;

    return sign + GenerateDaXieLng( lng ) + Yuan + GenerateDaXiePoint( dec - lng );
    }
    catch ( System.Exception ex )
    {
    throw ex;
    }
    } #region 获取整数部分大写
    /// <summary>
    /// 根据一个整数生成相应大写
    /// </summary>
    private static string GenerateDaXieLng( long lng )
    {
    if ( lng >= 100000000 )
    return GenerateDaXieLng( lng / 100000000 ) + NumYi + ( ( lng - lng / 100000000 * 100000000 ) < 10000000 && ( lng - lng / 100000000 * 100000000 ) != 0 ? Num0 : ""  ) + GenerateDaXieLng( lng - lng / 100000000 * 100000000 );
    else if ( lng >= 10000 )
    return GenerateDaXieLng( lng / 10000 ) + NumWan + ( ( lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 );
    else if ( lng >= 1000 )
    return GenerateDaXieLng( lng / 1000 ) + NumQian + ( ( lng - lng / 1000 * 1000 ) < 100 && ( lng - lng / 1000 * 1000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 1000 * 1000 );
    else if ( lng >= 100 )
    return GenerateDaXieLng( lng / 100 ) + NumBai + ( ( lng - lng / 100 * 100 ) < 10 && ( lng - lng / 100 * 100 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 100 * 100 );
    else if ( lng >= 10 )
    return GenerateDaXieLng( lng / 10 ) + NumShi + GenerateDaXieLng( lng - lng / 10 * 10 );
    else if ( lng > 0 )
    return DaXie(lng);
    else
    return ""; }
    #endregion #region 获取小数部分大写
    /// <summary>
    /// 获取小数部分大写
    /// </summary>
    private static string GenerateDaXiePoint( decimal dec )
    {
    if ( dec == 0 ) return Zheng;
    string str = dec.ToString();
    str = str.Substring( str.IndexOf(".") +1 ); return DaXie( Convert.ToInt64( str.Substring( 0,1 ) ) )  + Jiao + DaXie( Convert.ToInt64( str.Substring( 1,1 ) ) ) + Fen ;
    }
    #endregion #region 获取单个数对应的大写
    /// <summary>
    /// 获取单个数对应的大写
    /// </summary>
    private static string DaXie( long i )
    {
    switch (i)
    {
    case 9:
    return Num9;
    case 8:
    return Num8;
    case 7:
    return Num7;
    case 6:
    return Num6;
    case 5:
    return Num5;
    case 4:
    return Num4;
    case 3:
    return Num3;
    case 2:
    return Num2;
    case 1:
    return Num1;
    default:
    return Num0;
    }
    }
    #endregion  }
      

  4.   

    精华在这里:http://www.vckbase.com/bbs/prime/search.asp?r=900&s=1或:
    http://www.vckbase.com/bbs/prime/viewprime.asp?id=576
    // 货币金额大写转换库   Money2String.dll// 静态中文转换方法     String GetCnString(String MoneyString)
    // 最大转化金额         9999999999999999.99  (16位整数位,2位小数位)
    // 方法返回值           转换成功则返回非零长字串,否则返回零长字串// 静态英文转换方法     String GetEnString(String MoneyString)
    // 最大转化金额         999999999999999.99   (15位整数位,2位小数位)
    // 方法返回值           转换成功则返回非零长字串,否则返回零长字串
    // 程序设计 xlFancy     版本 2003.03.18.22 - 2003.04.09
    // 邮箱地址 [email protected]
      

  5.   

    我觉得应该先判断数字的长度,比如1000,那是千位的,10000是万位的,小数字都是从上往下算,那么大数字呢?比如1000 0000 0000就是1000亿,那恐怕就要先取到数字位数是否>=9并且小于18位位了.如果是,那么先截取前My.Length-8位,然后再对截取的进行处理,处理完再处理后面的
    因为亿一般都是我门用到的最大位数了.这样处理好象比较麻烦.从下往上取怎么样呢?
    这里就不说角很分了,问题类似
    可以用for循环来取
    可以在循环中替换成中文,我这里就不替换了
    public string My = 10000000 
    public string myString = null;public static main()
    {
          if(My.Length<9)
              myString = "";
              MyTest(My);
              //输出myString 
          else     //假设位数小于18,不考虑更大的情况
          {
              myString = "";
              MyTest(My.Substring(0,My.Length-9));
              myString += "亿"
              MyTest(My.Substring(My.Length-9,9));
              //输出myString 
          }
    }void MyTest(string My)
    {
    int len = My.Length;
    for(int i = 0;i<len ;i++)
    {
         switch(i)
         {
               case 0:
                     myString = My.Substring(len - i -1,1) + "员" + myString ;
                    break;
               case 1:
                     myString = My.Substring(len - i -1,1) + "拾"+ myString ;
                    break;
               case 2:
                     myString = My.Substring(len - i -1,1) + "佰"+ myString ;
                    break;
               case 3:
                     myString = My.Substring(len - i -1,1) + "仟"+ myString ;
                    break;
               case 4:
                     myString = My.Substring(len - i -1,1) + "萬"+ myString ;
                    break;
               case 5:
                    return MyTest(My.Substring(0,len - i));
                    break;
          }
    }
    }以上代码手写,出现错误,修改一下
      

  6.   

    请教一下 if ( lng >= 10000 )
        return GenerateDaXieLng(lng/10000) + NumWan + ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 );     是什么意思啊? 还有    string je = d.ToString("####.00");
                 if (je.Length > 15)
                 return "";
             je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0
      中 string je = d.ToString("####.00");是输出格式吗?
      je = new String('0',15 - je.Length) + je;为什么小于15位长,前面要补0?
      

  7.   

    请教一下 if ( lng >= 10000 )
        return GenerateDaXieLng(lng/10000) + NumWan + ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 );     是什么意思啊? 还有    string je = d.ToString("####.00");
                 if (je.Length > 15)
                 return "";
             je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0
      中 string je = d.ToString("####.00");是输出格式吗?
      je = new String('0',15 - je.Length) + je;为什么小于15位长,前面要补0?
      

  8.   

    GenerateDaXieLng(lng/10000) + NumWan  得到 N万
    ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) 判断万以下值是否大于1000(千位是否为零),小于1000加一个“零”
    GenerateDaXieLng( lng - lng / 10000 * 10000 );  得到 N千
      

  9.   

    ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) 判断万以下值是否大于1000(千位是否为零)且万以下是否等于零,小于1000万且大于零加一个“零”,
      

  10.   

    string je = d.ToString("####.00");
                 if (je.Length > 15)
                 return "";
             je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0  中   string je = d.ToString("####.00");        是输出格式吗?
          je = new String('0',15 - je.Length) + je;  为什么小于15位长,前面要补0?
      

  11.   

    // 例如:(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();
        }
      }
    }