柳州本地做网站的公司恩施做网站
关于大数值金额大写转换,在财务管理的应用方面没什么意义。一般来说,千亿级,万亿级的数值就够了。因为在国家级层面是以亿为单位的,也就表达为千万亿,万万亿。在企业层面数值金额转换设置到千亿、万亿就行了。大的集团级企业扩大到万万亿也就行了。做企业应用软件的可根据需要设置。至于再大的数值就是天文数字,有另外的表达方法。
本人喜欢探索各种算法。前些天写了15位数值的金额大写转换。今再尝试写一个更多位数值的换算大写转换。提供给需要的同道参考。
金额大写应用在很多方面,如支票、发票、各种单据,各种财务凭证,合同文本金额部分。财务方面制定了一套标准的表达法。财务上金额大写是没有负数的,财务上分借方和贷方,负数就是借方红字和贷方红字,也就是赤字。大写转换的算法要按财务管理的标准来设置。本文详细介绍算法的要点。
算法的要点:
 简单地讲就是字串转换处理。若输入是数值型则转为字串型。
 将输入的金额分成整数部分和小数部分,整数部分分段为4位数的万级段,再按金额数值逐位转换成中文,拼成大写字串,然后输出。
 对于不含零的情况,直接就转换好了。然而对于含零和连续多个零的情况就要消除多余的零。本文介绍的算法就是 ”截数值位消零法”,或称 ”截位消零法” 。
要处理的是整数部分,分四步:
 一是  将整数部分分成整数的前几位字段和后面的4位万级数字段,
 二是  按字段先换成2个字符的数字和单位的中文表达,
 三是  按2个字符截取字段, 将含零的字段消去单位,
 四是  处理多余的零,然后拼接整数和小数,输出大写。

  
转换的算法就一个函数:
 Function   convert (){   //传入 snum $ 输出金额大写 put$
 // M$="零元拾佰仟万拾佰仟亿拾佰仟兆拾佰仟京拾佰仟" ;
 M$="零元拾佰仟万拾佰仟亿拾佰仟万拾佰仟万拾佰仟" ;
  string pn$[50] ;
  string dn[8] ;   //中国式以每万为段,4位一段         
 //对输入字串截取整数部分和小数部分,
 //小数部分直接转换,整数部分按万级分段,
 //先处理整数的前几位,后处理后续的4位万级数,
 //最后拼接字串输出金额大写
    //snum="10020005600205" ;     //test
   g$= subString (snum, 0 ,1 ) ; 
   //输入 "0.56"     format >  " .56" 
     if(g$=="0") snum= subString (snum,1, 3)  ; 
          nlen=len(snum) ;
          n=nlen ;
     for (i=0; i<nlen ; i++){
          g$= subString (snum, i,1 ) ;
          if(g$==".") n= i ;    }
     if (nlen-n>2) sn$=subString (snum,n+1,2) ;
     if (nlen-n==2) sn$=subString (snum,n+1,1)+"0" ;
     if (nlen-n==0) sn$="00" ;    //无小数
     fn$=subString (snum,0,n) ;    //截取整数部分
          print "输入金额 snum = ", snum ;
         // print "整数部分 fn = ", fn$ ;       //test
         // print "小数角分 sn = ", sn$ ;
 //开始转换,先处理整数 fn$ ******
        chb$=""  ;   chs$=""  ;    chsd$=""  ;
 //角分小数部分 ******
       d1$=subString(sn$,0,1) ;
       d2$=subString(sn$,1,1) ;
         // print d1$ +"   "+d2$ ;     //test
    if (d1$=="0" ){
       c$="零" ; }else{
        a$=d1$ ;
        snToD ();  
        c$=c$+"角" ;      }
        d$ =c$ ;     
   
   if (d2$=="0" ){
        c$="整" ; }else{
        a$=d2$ ;
        snToD ();    
        c$=c$+"分" ;      }
        d$ =d$+c$ ;    
        chs$=d$  ;     //小数chs$已转换
        // print "chs$ = "+chs$ ;   //test
   if (d1$=="0"&&d2$=="0" ){   chs$="整"  ;   }
  
  //开始转换,处理整数 fn$ ******
  //4位段整数转换
         nlen=len (fn$) ;    //字串长度
         n=nlen/4 ;            //整数后4字数段位数
         k=nlen-nlen/4*4 ;     //mod 整数前几位
             // print "Input fn$ = " + fn$ ;   //test
             // print "长串前面几位  k = " , k ;
             // print "长串后 4 字段 n = " , n ;
        d1$=subString (fn$, 0, k) ;
        d2$=subString (fn$, k, nlen) ;
             // print "d1$ = " + d1$ ;    //test
             // print "d2$ = " + d2$ ;
    //整数前几位转换
    for (i=0; i<k ; i++){   //
          a$= subString (d1$, i, 1 ) ;
          snToD () ;      //数字转大写 得c$
           b$=subString (M$, k - i+n*4,1) ;
           p$=subString (N$, n*4+i, 1) ;
           chsd$=chsd$+c$+b$ ;    }    //整数前几位 
          // print "chsd$ = " + chsd$  ;   //test
 //**** 整数前几位完成 chsd$
            p$="" ;
      for (i=0; i<n ; i++){   //整数后4数段位截串
            dn[i]= subString (d2$, i*4 , 4 ) ;   
            p$=p$+ dn[i] +"" ;        }
            // print "p$ = "+p$ ;       //test
int du ;    // 4 位数段
         for (du=0; du<n ; du++){  //按整数4数段位转换
           p$="" ;
       for (i=0; i<4 ; i++){   //
          a$= subString (dn[du], i, 1 ) ;
          snToD () ;      //数字转大写 得c$
          b$=subString (M$, n*4-du*4 - i ,1) ;   //单位
          p$=p$+c$+b$ ; 
          pn$[i]=c$+b$ ;     }    //整数后4字数段
           chb$=chb$+p$ ;       }    //du
      chb$=chsd$+chb$ ;  
      //   print "chb$ = "+chb$ ;   //含零整数完成test
  //***************
    p$=" " ;
       nlen=len (chb$)/2 ;   //按中文二字组字串
       // for (i=0; i<30 ; i++){  pn$[i]=" " ;  }
    for (i=0; i<nlen ; i++){
           pn$[i]=subString(chb$, i*2, 2) ;   }
   //按位数转换成大写 format 消单位 **********
            p1$="" ;    p2$="" ;
            p$="" ;
     for (k=0; k<nlen ; k++){
            p1$=pn$[k] ;
         if (p1$=="零仟") { pn$[k]="零" ;    }
         if (p1$=="零佰") { pn$[k]="零" ;    }
         if (p1$=="零拾") { pn$[k]="零" ;    }
         if (p1$=="零元") { pn$[k]="元" ;    }
         if (p1$=="零万") { pn$[k]="万" ;    }
         if (p1$=="零亿") { pn$[k]="亿" ;    }
                  }  //format
          p$="" ;
    for (m=0; m<nlen ; m++){  //重组整数部分>去零
           p$=p$+pn$[m] ;    }
          // print p$ ;    //test
           nlen= len (p$) ;
   for (i=0; i<nlen ; i++){    //renew p$
           pn$[i]=subString(p$, i, 1) ;   }
  for (m=0; m<nlen ; m++){   //去多余 ”零”
             p1$=pn$[m] ;
        if (p1$=="零"&&pn$[m+1]=="零" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="元" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="万" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="亿" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="兆" ) {  pn$[m]="" ;  }       
              }
       //   print p1$ ;    //test
    chb$=" " ;
     for (i=0; i<nlen ; i++){   //去零后重组整数部分
             chb$=chb$+pn$[i] ;      } 
 //特殊情况100000902  大写: 壹亿万零玖佰零贰元整
 //测试时碰到此例 ”壹亿万零... ”  要消 "万" ****
 //用京兆需要下列代码,用万亿、万万亿不需要
          nlen= len (chb$) ;
    for (i=0; i<nlen ; i++){   //特殊情况,消”万”  ”亿”
          a$=subString (chb$, i, 1 )  ;
          b$=subString (chb$, i+1, 1 )  ;
      if (a$=="亿"&&b$=="万") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$= a$+b$ ;   }   
       if (a$=="兆"&&b$=="亿") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$=chb$+a$+b$ ;   }   }
       nlen= len (chb$) ;
    for (i=0; i<nlen ; i++){   //特殊情况,消”万”
          a$=subString (chb$, i, 1 )  ;
          b$=subString (chb$, i+1, 1 )  ;
      if (a$=="兆"&&b$=="万") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$=chb$+a$+b$ ;   }     } 
    chb$=chb$+chs$ ;     //整数小数拼接,完成转换
       if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") {
             chb$= " 零元整" ;      }     
 //输出结果 ****** 
        print " 大写输出:" ;     
            put$=chb$ ;
        print  put$ ;        //转换完成输出
        print "...................................." ;
}//convert ()

 //以下是完整的设计测试源码:
 // ****  财务金额大写显示  **************
 // 本代码是用简单的 C 语言写的,用 MySpringC
 //  v2.7 编译调试通过。可以 VB6, C++, Java 改写。
 // 编译人:张纯叔(micelu@126.com )
 //*******************************************
  string sBarDes[10];
  int nBarId[10];
  string snum, put$ ;    //传入金额,输出大写
  int n, i, j, k, m ;
  string N$ , M$, D$ ;   //预设置大写字符
  string a$, c$;     //转换 传入a$ 输出c$
  string d$, d1$, d2$ ;    //计算小数角分
  string fn$, sn$ ;    //整数字串,小数字串
  string chs$, chb$, chsd$ ; //小写,大写,整数首段
  int nlen ;             //Len 字数
  string b$, g$, p$, p1$, p2$ ;    //计算
main(){
 setDisplay (0);
    sBarDes[0]="输入金额";
    nBarId[0]=100;
    sBarDes[1]=" 测  试 ";
    nBarId[1]=101;
    sBarDes[2]=" 示  例 ";
    nBarId[2]=102;
    sBarDes[3]="  ";
    nBarId[3]=103;
    sBarDes[4]="退出程序 ";
    nBarId[4]=104;
    setToolBarHeight(10);
    setButtonTextSize(15);
   setToolBarBackgroundColor(255,220,220,220);
    setButtonColor(255,240,240,240);
    setButtonTextColor(255,0,0,200);
    setToolBar(100,myToolBarProc,sBarDes,nBarId,6);
     setTitle("金额大写转换"); 
  while (){}
 }//main ()
  convert (){   //传入 snum $ 输出金额大写 put$
 // M$="零元拾佰仟万拾佰仟亿拾佰仟兆拾佰仟京拾佰仟" ;
 M$="零元拾佰仟万拾佰仟亿拾佰仟万拾佰仟万拾佰仟" ;
  string pn$[50] ;
  string dn[8] ;   //中国式以每万为段,4位一段         
 //对输入字串截取整数部分和小数部分,
 //小数部分直接转换,整数部分按万级分段,
 //先处理整数的前几位,后处理后续的4位万级数,
 //最后拼接字串输出金额大写
    //snum="10020005600205" ;     //test
   g$= subString (snum, 0 ,1 ) ; 
   //输入 "0.56"     format >  " .56" 
     if(g$=="0") snum= subString (snum,1, 3)  ; 
          nlen=len(snum) ;
          n=nlen ;
     for (i=0; i<nlen ; i++){
          g$= subString (snum, i,1 ) ;
          if(g$==".") n= i ;    }
     if (nlen-n>2) sn$=subString (snum,n+1,2) ;
     if (nlen-n==2) sn$=subString (snum,n+1,1)+"0" ;
     if (nlen-n==0) sn$="00" ;    //无小数
     fn$=subString (snum,0,n) ;    //截取整数部分
          print "输入金额 snum = ", snum ;
         // print "整数部分 fn = ", fn$ ;       //test
         // print "小数角分 sn = ", sn$ ;
 //开始转换,先处理整数 fn$ ******
        chb$=""  ;   chs$=""  ;    chsd$=""  ;
 //角分小数部分 ******
       d1$=subString(sn$,0,1) ;
       d2$=subString(sn$,1,1) ;
         // print d1$ +"   "+d2$ ;     //test
    if (d1$=="0" ){
       c$="零" ; }else{
        a$=d1$ ;
        snToD ();  
        c$=c$+"角" ;      }
        d$ =c$ ;     
   
   if (d2$=="0" ){
        c$="整" ; }else{
        a$=d2$ ;
        snToD ();    
        c$=c$+"分" ;      }
        d$ =d$+c$ ;    
        chs$=d$  ;     //小数chs$已转换
        // print "chs$ = "+chs$ ;   //test
   if (d1$=="0"&&d2$=="0" ){   chs$="整"  ;   }
  
  //开始转换,处理整数 fn$ ******
  //4位段整数转换
         nlen=len (fn$) ;    //字串长度
         n=nlen/4 ;            //整数后4字数段位数
         k=nlen-nlen/4*4 ;     //mod 整数前几位
             // print "Input fn$ = " + fn$ ;   //test
             // print "长串前面几位  k = " , k ;
             // print "长串后 4 字段 n = " , n ;
        d1$=subString (fn$, 0, k) ;
        d2$=subString (fn$, k, nlen) ;
             // print "d1$ = " + d1$ ;    //test
             // print "d2$ = " + d2$ ;
    //整数前几位转换
    for (i=0; i<k ; i++){   //
          a$= subString (d1$, i, 1 ) ;
          snToD () ;      //数字转大写 得c$
           b$=subString (M$, k - i+n*4,1) ;
           p$=subString (N$, n*4+i, 1) ;
           chsd$=chsd$+c$+b$ ;    }    //整数前几位 
          // print "chsd$ = " + chsd$  ;   //test
 //**** 整数前几位完成 chsd$
            p$="" ;
      for (i=0; i<n ; i++){   //整数后4数段位截串
            dn[i]= subString (d2$, i*4 , 4 ) ;   
            p$=p$+ dn[i] +"" ;        }
            // print "p$ = "+p$ ;       //test
int du ;    // 4 位数段
         for (du=0; du<n ; du++){  //按整数4数段位转换
           p$="" ;
       for (i=0; i<4 ; i++){   //
          a$= subString (dn[du], i, 1 ) ;
          snToD () ;      //数字转大写 得c$
          b$=subString (M$, n*4-du*4 - i ,1) ;   //单位
          p$=p$+c$+b$ ; 
          pn$[i]=c$+b$ ;     }    //整数后4字数段
           chb$=chb$+p$ ;       }    //du
      chb$=chsd$+chb$ ;  
      //   print "chb$ = "+chb$ ;   //含零整数完成test
  //***************
    p$=" " ;
       nlen=len (chb$)/2 ;   //按中文二字组字串
       // for (i=0; i<30 ; i++){  pn$[i]=" " ;  }
    for (i=0; i<nlen ; i++){
           pn$[i]=subString(chb$, i*2, 2) ;   }
   //按位数转换成大写 format 消单位 **********
            p1$="" ;    p2$="" ;
            p$="" ;
     for (k=0; k<nlen ; k++){
            p1$=pn$[k] ;
         if (p1$=="零仟") { pn$[k]="零" ;    }
         if (p1$=="零佰") { pn$[k]="零" ;    }
         if (p1$=="零拾") { pn$[k]="零" ;    }
         if (p1$=="零元") { pn$[k]="元" ;    }
         if (p1$=="零万") { pn$[k]="万" ;    }
         if (p1$=="零亿") { pn$[k]="亿" ;    }
                  }  //format
          p$="" ;
    for (m=0; m<nlen ; m++){  //重组整数部分>去零
           p$=p$+pn$[m] ;    }
          // print p$ ;    //test
           nlen= len (p$) ;
   for (i=0; i<nlen ; i++){    //renew p$
           pn$[i]=subString(p$, i, 1) ;   }
  for (m=0; m<nlen ; m++){   //去多余 ”零”
             p1$=pn$[m] ;
        if (p1$=="零"&&pn$[m+1]=="零" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="元" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="万" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="亿" ) {  pn$[m]="" ;  }       
        if (p1$=="零"&&pn$[m+1]=="兆" ) {  pn$[m]="" ;  }       
              }
       //   print p1$ ;    //test
    chb$=" " ;
     for (i=0; i<nlen ; i++){   //去零后重组整数部分
             chb$=chb$+pn$[i] ;      } 
 //特殊情况100000902  大写: 壹亿万零玖佰零贰元整
 //测试时碰到此例 ”壹亿万零... ”  要消 "万" ****
 //用京兆需要下列代码,用万亿、万万亿不需要
          nlen= len (chb$) ;
    for (i=0; i<nlen ; i++){   //特殊情况,消”万”  ”亿”
          a$=subString (chb$, i, 1 )  ;
          b$=subString (chb$, i+1, 1 )  ;
      if (a$=="亿"&&b$=="万") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$= a$+b$ ;   }   
       if (a$=="兆"&&b$=="亿") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$=chb$+a$+b$ ;   }   }
       nlen= len (chb$) ;
    for (i=0; i<nlen ; i++){   //特殊情况,消”万”
          a$=subString (chb$, i, 1 )  ;
          b$=subString (chb$, i+1, 1 )  ;
      if (a$=="兆"&&b$=="万") { 
            a$=subString (chb$, 1, i) ;  
            b$=subString (chb$, i+2, nlen-i ) ;                  
            chb$=chb$+a$+b$ ;   }     } 
    chb$=chb$+chs$ ;     //整数小数拼接,完成转换
       if (snum=="."||snum==".0"||snum==".00"||snum=="0."||snum==" ") {
             chb$= " 零元整" ;      }     
 //输出结果 ****** 
        print " 大写输出:" ;     
            put$=chb$ ;
        print  put$ ;        //转换完成输出
        print "...................................." ;
}//convert ()

test (){  //数值含零空位算法测试
        clearOutput ();
    print "特殊数值检测检验:" ;
    snum="20000100300000000" ;
         convert () ;
    snum="100000902" ;
         convert () ;
    snum="20005600205" ;
         convert () ;
    snum="3060002065" ;
         convert () ;
   snum="10508005.75" ;
         convert () ;
   snum="50700650.5" ;
         convert () ;
   snum="1802065.06" ;
         convert () ;
 }//test ()
 
sample (){
    clearOutput ();
    print "输出示例:" ;
    snum="30600702" ;
        convert () ;
    snum="1500903.08" ;
         convert () ;
    snum="1020697.00" ;
         convert () ;
    snum="159533.65" ;
         convert () ;
    snum="282581697.50" ;
         convert () ;
    snum="520967.56248" ;
         convert () ;
   snum="2801697.00" ;
         convert () ;
  }//sample() 
snToD (){   //传入a$  返回c$
   N$="零壹贰叁肆伍陆柒捌玖" ;
         if (a$=="0") c$=subString (N$,0,1) ;
         if (a$=="1") c$=subString (N$,1,1) ;
         if (a$=="2") c$=subString (N$,2,1) ;
         if (a$=="3") c$=subString (N$,3,1) ;
         if (a$=="4") c$=subString (N$,4,1) ;
         if (a$=="5") c$=subString (N$,5,1) ;
         if (a$=="6") c$=subString (N$,6,1) ;
         if (a$=="7") c$=subString (N$,7,1) ;
         if (a$=="8") c$=subString (N$,8,1) ;
         if (a$=="9") c$=subString (N$,9,1) ;
 }//snToD ()
input (){//输入
 string m;
     snum=stringInput (" 输入金额转大写 ","   输入金额小写   例: 3572689.36  \n        ( 输出金额大写  )\n    输入 [ 空 ]  退出 " ) ;
           clearOutput ();
          print "Input  金额 = ",snum ;
     if (snum=="") {  snum=".00"  ;  
          print "输入为空,请重新输入。 "  ;     }
      convert () ;
 }//input ()
myToolBarProc(int nBtn,int nContext) {
       if(nBtn==100){//输入金额
             input ();           }
       if(nBtn==101){  //test 测试       
              test () ;           }
        if(nBtn==102){//示例
             sample ();           }
       if(nBtn==103){//算法测试
              // convert () ;    
                     }
       if(nBtn==104){//退出程序
           clearOutput();
           exit (0);            }
 }//myToolbar ()
//**** End ****
