`
bardo
  • 浏览: 372006 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
D1407912-ab64-3e76-ae37-b31aa4afa398
浅述PHP设计模式
浏览量:11605
9d6df9f7-91da-3787-a37c-0e826525dd5d
Zend Framewor...
浏览量:9978
85b628bd-a2ed-3de2-a4b1-0d34985ae8b6
PHP的IDE(集成开发环...
浏览量:9333
社区版块
存档分类
最新评论

重发《人民币金额转大写程序 jsp, Java版》

    博客分类:
  • JSP
 
阅读更多
//人民币金额转大写程序 jsp, Java版
//CopyRight Bardo QI
//所以重发这个版本,是因为:http://zhangshangfeng.iteye.com/
//这位老兄没能看懂我前期所发的无注解的,并且未经测试的代码。
//代码原发是在:http://bardo.iteye.com/blog/983559
//其实:写程序只要记住一点:“不要跟着数据走!”那么代码量
//就会增加多少。
//为了能使初学者有所认识,这里对此代码讲解一下:

import java.util.ArrayList;
import java.util.Math.*;
import java.lang.*;
String numToCny(String num){
    //这个变量定义是基于一个基本思想的,那就是,关于汉语数字的读法:
/*********************************************************
汉语的数字读法,有以下口诀:
四位分级,读准位级。
有数读位,个零不读。
多零连续,只读一次。
尾零不读,级不可丢。
本级为零,本级不读。
遇有小数,整零要读。
小数读数,零要分读。
现详细讲解如下:
四位分级,读准位级。 
    如:111111111111 读法:壹仟壹佰壹拾壹亿壹仟壹佰壹拾壹万壹仟壹佰壹拾壹。 即111111111111 分为:1111亿级,1111万级,1111个级,每级都有 仟佰拾个四个位。非零数,读出数与位,到级时,读出级。 
有数读位,个零不读。 
    101 读法:壹佰零壹 而不是:壹佰零拾壹个。即:对于0,只读数,不读位,个位的数,不读位(个字不读)
多零连续,只读一次。 
    1001 读法:壹仟零壹 而不是:壹仟零零壹。即:遇有多个连续的0,只读一次。 
尾零不读,级不可丢。 
    102345 读法:壹拾万贰仟叁佰肆拾伍 而不是:壹拾万零贰仟叁佰肆拾伍 100 读法:壹佰 而不是壹佰零。即按级来分,任一级的尾零都不读。但亿级的亿,万级的万,有尾零时仍要读的
本级为零,本级不读。 
    100002345  读法:壹亿贰仟叁佰肆拾伍圆整 而不是:壹亿零万贰仟叁佰肆拾伍圆整。 即,如果任一级四位全零,那么,不管前后是否有数,都不读。
遇有小数,整零要读。 
    0.23  读法:零点贰叁。即,如果有小数时,整数如果是零,则要读的。
小数读数,零要分读。 
    12.3004 读法:壹拾贰点叁零零肆。 即:小数无位,只是见数读数。 
**********************************************************/
      //为此,这一代码的基本思想就是先对数据进行预处理
    //将期转换成 0000 0000 0000 0000.00 这一形式
    //自然,空格是额外加上的。基本数是12位。所以,最高一级
    //这里用的是“万”来表示的。有人提出用“兆”,但有误解,
    //真要想用,只要能懂即可。		
    String capUnit[] ={"万","亿","万","圆",""};
      //下面这个变量,是这样定义的,每一节都是四位,只有小数是两位。
    //所以,用二维数组,第2项是{"角","分",""},第4项上{"仟","佰","拾",""}
      //这样做,我们可以用当前节的长度获得每一位的单位。这样,就不要用对象了。
    String capDigit[][] = { {""},{""},{"角","分",""},{""},{"仟","佰","拾",""}};
      //以下是数字与汉字对应,无需解释
    String capNum[]={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
      //原发是参数是双精度的。但由于操作系统会将其转为科学记数法,所以,现改为字串
    //因为整数最多是16位,所以,超出就不转了
    if (num.indexOf(".") > 16)
        return "ERROR";
      //转成双精度数
    double dnum=Double.parseDouble(num);
      //如果不是数字,不转了。
    if (Double.isNaN(dnum))
        return "ERROR";
      //做保留两位小数的操作
    dnum = Math.round(dnum*100)/100;
      //再转回字符串	
    String snum = Double.toString(dnum);
      //这里是造出一串0,补到原数前面
    double pnum = Math.pow(10,19-snum.length());
      String psnum = Double.toString(pnum);
      //psnum前面有个1,所以,把1去掉,与原数补起来
    //结果就是标准的整数16位,小数两位,中间有点的字串了。
    snum = psnum.substring(1)+snum;
      //由此,我们没花几行代码,对数据进行预处理,所以,后面代码就是完全
    //针对我们预处理好的完全符合我们要求的数据进行编码了,自然代码会很少。
    //定义好要用的变量
    String ret,nodeNum,subret,subChr;
    ArrayList CurChr = new ArrayList(2);
    int i,j=0,k,len;
    //这一循环,是按节循环,但关键是在j=i*4+(int)Math.floor(i/4)
    for (i=0,ret="";i<5;i++,j=i*4+(int)Math.floor(i/4)){
           //每次取出4位,自然,小数点以后的,因为j=i*4+(int)Math.floor(i/4)
	//把小数点跳过去了。并且只能取出两位
        nodeNum=snum.substring(j,j+4);
	//对当前取出的四位进行循环处理,此时处理时,按取出的实际字串的长度循环。这个条件:len=nodeNum.length()
	//同时,如果尾部有零,也不继续,这一条件:(Integer.parseInt(nodeNum.substring(k))!=0)
        for(k=0,subret="",len=nodeNum.length();((k<len) && (Integer.parseInt(nodeNum.substring(k))!=0));k++){
        //为什么要用 CurChr 这个 ArrayList,而且每次访问的都是k%2这一元素?
	//这是要保存上一次的结果,供本次使用
           //capNum[Integer.parseInt(nodeNum.substring(k,k+1))]是把阿拉伯数字对应到汉字
	//而((nodeNum.substring(k,k+1).equals("0"))?"":capDigit[len][k]) 则是对非零的
           //读出对应的位的单位:千,佰,拾,"", 注意,这里有个特别的,是用 len 去读的对
	//应二维数组中的项,所以,如果是两位,自然读出的就是“角”“分”
CurChr.set(k%2,capNum[Integer.parseInt(nodeNum.substring(k,k+1))]+((nodeNum.substring(k,k+1).equals("0"))?"":capDigit[len][k]));
            //这是全部代码中的第三个IF。基本目的,是不让在整数中出现“零零”这样的字样。如果上一次与本次不等。并且,数字前面不为0
            if (!((CurChr.get(0)==CurChr.get(1)) && (CurChr.get(0)==capNum[0])))
                //假如本次不为0,并且,己有非零数字,同时,上一级也有非零数字
		//那么,把当前的“零”字加上来。
                if(!((CurChr.get(k%2) == capNum[0]) && (subret.equals(""))  && (ret.equals(""))))
                    subret += CurChr.get(k%2);
        }
	//如果上一级返回不是“”,在上面的循环结果后面加上级的单位。
        subChr = subret + ((subret.equals(""))?"":capUnit[i]);
            //只要当前结果不是零,或者,全部己得的结果不空,则就将当前结果接上去。
        if(!((subChr == capNum[0]) && (ret.equals(""))))
            ret += subChr;
    }
     //如果最后还是空,返回“零圆”。其实,此代码还有未完善的功能,那就是,无角分的,没有在最后加上“整”字。但这是很容易的。	
    ret=(ret.equals(""))? capNum[0]+capUnit[3]: ret;
    return ret;
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics