haoxiaobo

从C到C++又到.net, 有一些心得, 和大家交流下...
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

费了九牛二虎之力才搞定的大写数字转换的代码.

Posted on 2005-01-11 11:40  HAL9000  阅读(2666)  评论(6编辑  收藏  举报
最简单的事情最麻烦, 希望已经没有BUG了.
using System;
using System.Collections;
using System.IO;
using System.Text;

namespace HXBTools.Util
{
    
/// <summary>
    
/// 用于将一个数值型转化为汉语的读法.
    
/// </summary>

    public class NumberToChn
    
{
        
public NumberToChn()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }


        
public static string GetChn(decimal dc, bool bUpper)
        
{
            
return GetChn(dc.ToString(), bUpper);
        }


        
public static string GetChn(int i, bool bUpper)
        
{
            
return GetChn(i.ToString(), bUpper);
        }


        
public static string GetChn(long l, bool bUpper)
        
{
            
return GetChn(l.ToString(), bUpper);
        }
        

        
public static string GetRMBChn(string sDigital, bool bUpper)
        
{
            
// 找出第一个点所在的位置,之前的部分用getchn来处理,之后的部分自已处理.
            if (sDigital == null | sDigital.Length == 0)
                
return "";

            
int iIndex = sDigital.IndexOf(".");
            
string sIntPart;
            
string sDecPart;
            
if (iIndex == -1)
            
{
                sIntPart 
= sDigital;
                sDecPart 
= "";
            }

            
else
            
{
                sIntPart 
= sDigital.Substring(0, iIndex);
                sDecPart 
= sDigital.Substring(iIndex+1);
            }


            StringBuilder sb 
= new StringBuilder(sDigital.Length * 2 + 10);
            
foreach(char c in sDecPart)
            
{
                
if ( char.IsDigit(c))
                
{
                    sb.Append(c);
                }

            }

            sDecPart 
= sb.ToString();
            sb.Length 
= 0;

            
string sTmp = GetChn(sIntPart, bUpper);
            
if (sTmp != "" && sTmp.Length != 0)
            
{
                sb.Append(sTmp);
                sb.Append(bUpper
?'':'');            
            }

            
            
bool bPrevIsZero = false;
            
if (sIntPart.Length > 0 && sIntPart.EndsWith("0"&& sb.Length > 1)
            
{
                bPrevIsZero 
= true;
            }

            
for (int i = 0; i < sDecPart.Length && i < arRMBRight.Length; i ++)
            
{
                
if (sDecPart[i] == '0')
                
{
                    bPrevIsZero 
= true;
                }

                
else
                
{
                    
if (bPrevIsZero == true)
                    
{
                        sb.Append(
'');
                        bPrevIsZero 
= false;
                    }

                    sb.Append(bUpper
?arDigitals2[sDecPart[i] - '0']:arDigitals[sDecPart[i] - '0']);
                    sb.Append(arRMBRight[i]);
                }

            }

            
if (sb.Length > 0)
            
{
                sb.Append(
'');
            }

            
else
            
{
                sb.Append(bUpper
?"零园整":"零元整");
            }

            
return sb.ToString();
        }


        
public static string GetChn(string s, bool bUpper)
        
{
            
// 先将s过滤,删除所有的非数字字符。
            if (s == null || s.Trim().Length == 0)
                
return "";
            StringBuilder sb 
= new StringBuilder(s.Length);
            
int iPointCount = 0;
            
for(int i = 0; i < s.Length; i ++)
            
{
                
char c = s[i];
                
if (Char.IsDigit(c))
                
{
                    sb.Append(c);
                }

                
else if (c == '.')
                
{
                    
// 如果是第二个之后的点,那么不管了。
                    if (iPointCount == 0)
                    
{
                        sb.Append(c);
                        iPointCount 
++;
                    }
                                        
                }

                
else if( c == '-' && i == 0
                
{
                    sb.Append(c);
                }

                
else
                
{
                    
// 省下的全部忽略
                }

            }


            
string sDigital = sb.ToString();
            
if (sDigital.EndsWith("."))
            
{
                sDigital 
= sDigital.Substring(0,sDigital.Length - 1);
            }

            
if (sDigital.Length == 0)
            
{
                sDigital 
= "0";
            }

            
            sb.Length 
= 0// 留为后用。
            
            
// 从小数点前后分为两部分
            int iTmp = sDigital.IndexOf('.');
            
string sIntPart;
            
string sDecimalPart;
            
if (iTmp == -1)
            
{
                sIntPart 
= sDigital;
                sDecimalPart 
= "";
            }

            
else
            
{
                sIntPart 
= sDigital.Substring(0, iTmp);
                sDecimalPart 
= sDigital.Substring(iTmp+1);
            }


            
// 处理小数点之前的部分

            
// 先决定最高位是什么位,再依次地向后拼出。
            
// 大循环是亿的个数, 小循环是万的个数。
            
            sb 
= new StringBuilder(sDigital.Length * 2 + 6);
            
if (sDigital.StartsWith("-"))
            
{
                sb.Append(
"");
                sIntPart 
= sIntPart.Substring(1);
            }

            
// 如果小数点之后没有内容,之前部分又是空,那么不输出.
            if (sIntPart.Length == 0 && sDecimalPart.Length == 0)
            
{
                
return "";
            }


            
int iBitCntInWan = 0;
            
bool bPrevIs0 = false;
            
int iWanNotZeroCnt = 0;
            
int iNotZeroCnt = 0;

            
for (int i = 0; i < sIntPart.Length; i ++)
            
{
                
int iBitCnt = sIntPart.Length - i -1;

                
char cNum = sIntPart[i];
                
if (cNum == '0')
                
{
                    
// 如果是零,那么不处理
                    bPrevIs0 = true;
                }

                
else
                
{
                    
if (bPrevIs0)
                    
{
                        
// 如果上一个是0
                        if(iNotZeroCnt > 0)
                        
{
                            
//如果不是第一个字 那么加一个零字                                    
                            sb.Append(bUpper?arDigitals2[0]:arDigitals[0]);
                        }
                                
                    }

                    iWanNotZeroCnt 
++;
                    iNotZeroCnt 
++;

                    bPrevIs0 
= false;
                    sb.Append(bUpper
?arDigitals2[cNum - '0']:arDigitals[cNum - '0']);    // 加数名
                    iBitCntInWan = iBitCnt % 4;
                    
if (iBitCntInWan != 0)
                    
{
                        sb.Append(bUpper
?arRights2[iBitCntInWan]:arRights[iBitCntInWan]);    // 加权名
                    }

                }


                
if (iBitCnt % 8 == 0)
                
{
                    
// 遇亿的处理
                    if (iBitCnt / 8 >= 1 && iNotZeroCnt > 0 )
                        sb.Append(
'亿');
                    bPrevIs0 
= false;
                    iWanNotZeroCnt 
= 0;
                }

                
else if (iBitCnt % 4 == 0)
                
{
                    
// 遇万位的处理
                    if ((iBitCnt % 8)/4 >= 1 && iWanNotZeroCnt > 0 )
                    
{
                        sb.Append(
'');
                    }

                    bPrevIs0 
= false;
                    iWanNotZeroCnt 
= 0;
                }

            }



            
// 如果全部都是0,那么输出一个"零".
            if (iNotZeroCnt == 0)
            
{
                sb.Append(
"");
            }
            

            
// 处理小数点之后的部分
            if(sDecimalPart.Length != 0)
            
{
                sb.Append(
"");
                
for(int i = 0;  i < sDecimalPart.Length; i ++)
                
{
                    sb.Append(bUpper
?arDigitals2[sDecimalPart[i]-'0']:arDigitals[sDecimalPart[i]-'0']);
                }

            }

            iTmp 
= 0;
            
if (sb[0== '')
            
{
                iTmp 
=1;
            }


            
// 把起头的"一十"改为"拾".
            if (sb.Length >= 2)
            
{
                
if (sb[iTmp] == (bUpper?arDigitals2[1]:arDigitals[1]) && 
                    sb[iTmp 
+ 1== (bUpper?arRights2[1]:arRights[1]))
                
{
                    sb.Remove(iTmp,
1);
                }

            }

            
return sb.ToString();
        }


        
private static char [] arRights = {' '''''''}// 权名
        private static char [] arRights2 = {' '''''''}// 权名

        
private static char [] arDigitals = {
                                              
'','','','','','','','','',''
                                              }
;
        
private static char [] arDigitals2= {
                                                
'','','','','','','','','',''
                                            }
;

        
private static char [] arRMBRight = {''''''''''};

    }

}