一、把阿拉伯数字转换成中文人民币读法

  要求:

  1、得到一串整型数的整数部分和小数部分,并得到整数类型数小数和整数部分的位数。

  2、把整数部分的数转换成RMB的读法。

  主要问题:

  1、浮点数运算是容易造成精度丢失的问题。用BigDecimal可以实现高精度的运算。

  2、如何遍历每一个数,并得到这个数对应的大写读法。用char转int可以实现

代码实现

  1 import java.math.BigDecimal;
  2 
  3 /**
  4  * @ClassName: Num2Rmb
  5  * @author: 追雨的BigMouse
  6  * @Description:将一串数字转化成人民币的读法。
  7  *
  8  */
  9 public class Num2Rmb {
 10     private String[] hanRmb = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
 11     private String[] hanNum = {"十","百","千","万"};
 12     /**
 13      * @Method: numberLength
 14      * @Description:分解出来的整数部分和小数部分,并计算位数。
 15      * @return:以数组形式返回给定数的整数和小数的位数。数组的第一个元素是整数部分位数,第二个元素是整数部分,第三个元素是小数部分位数,第四个元素是小数部分
 16      */
 17     private double[] numberLength(double num){
 18         long zhengNum = (long)num;//得到数字的整数部分
 19         //调用自定义的高精度减法函数得到小数部分
 20         double xiaoNum = sub(num,zhengNum);
 21         //double xiaoNum = num-zhengNum;//这种方法会丢失精度
 22         //System.out.println(xiaoNum);    
 23         //判断整数的位数
 24         int i = 0;
 25         for(;;i++){
 26             double iPow = Math.pow(10, i);
 27             long numLengh = (long)(zhengNum/iPow);
 28             if(numLengh==0){
 29                 //System.out.println(i);
 30                 break;
 31             }
 32         } 
 33         //判断小数的位数 
 34         int j = 0;
 35         double mulXiaoNum = mul(xiaoNum, 10);
 36         double xiao = 0;
 37         for(;;){
 38             //double jPow = Math.pow(10, j);//同样会引起精度丢失问题
 39             j++;
 40             double checkNum = sub(mulXiaoNum, (long)mulXiaoNum);
 41             //System.out.println(checkNum+"f_"+mulXiaoNum+"d_"+(long)(mulXiaoNum));
 42             //System.out.println("叠加"+mulXiaoNum);
 43             if(checkNum==0){
 44                 //System.out.println(j);
 45                 xiao = (long)mulXiaoNum;//得到小数部分,但是如果小数点后一位是0则会被舍掉。
 46                 break;
 47             }
 48             mulXiaoNum=mul(mulXiaoNum, 10);
 49         } 
 50         //System.out.println(i+"_"+j);
 51         //return new double[]{i,zhengNum,j,xiao};    //以数组形式返回给定数的整数和小数的位数
 52         return new double[]{i,zhengNum,j,xiaoNum};    //所以小数部分还是保留小数点
 53     }
 54     //数字转人民币读法
 55     /**
 56      * @method numToRMB
 57      * @param num
 58      * @return 人民币读法
 59      */
 60     String result = "";
 61     public String numToRMB(double num){
 62         double[] numLength = numberLength(num);
 63         String zhengPart = numLength[1]+"";
 64         for(int i = 0;i<numLength[0];i++){
 65             //把char型字符串换成int型数,因为他们的ASCII码恰好相差48.即可将char转换成int型,如'4'转换成4。
 66             //charAt(int index)用来索引特定字符串的每一个字符。
 67             int intNum = zhengPart.charAt(i)-48;
 68             if(i != numLength[0]-1 && intNum!=0){
 69                 result += hanRmb[intNum]+hanNum[(int) (numLength[0]-2-i)];
 70             }else{
 71                 result += hanRmb[intNum];
 72             }
 73         }
 74         return result;
 75     }
 76     //先写一个自定义的高精度减法公式
 77     //这里直接做浮点数减法会导致精度丢失,为了能精确计算,用java类提供的BigDecimal类。
 78     //首先把数转换成字符串。 因为在创建BigDecimal对象时,一定要使用String对象作为构造器参数,否者依然无法精确计算。
 79     //有三种基本类型转字符串方法。还有,String stringNum = Double.toString(num);String stringZhengNum = String.valueOf(zhengNum);
 80     /**
 81      * @method: sub
 82      * @param num1
 83      * @param num2
 84      * @Description:进行高精度的减法
 85      * @return subNum 返回两double类型的数想减的值
 86      */
 87     private static double sub(double subNum1,double subNum2){
 88         String stringSubNum1 = subNum1+"";
 89         String stringSubNum2 = subNum2+"";
 90         BigDecimal BDSubnum1 = new BigDecimal(stringSubNum1);
 91         BigDecimal BDSubNum2 = new BigDecimal(stringSubNum2);
 92         double subNum = BDSubnum1.subtract(BDSubNum2).doubleValue();
 93         return subNum;
 94         
 95     }
 96     //再定义一个乘法
 97     /**
 98      * 
 99      * @param mulNum1
100      * @param mulNum2
101      * @return 返回两个数的乘积
102      */
103     private static double mul(double mulNum1,double mulNum2){
104         String stringMulNum1 = mulNum1+"";
105         String stringMulNum2 = mulNum2+"";
106         BigDecimal BDMulNum1 = new BigDecimal(stringMulNum1);
107         BigDecimal BDMulNum2 = new BigDecimal(stringMulNum2);
108         double mulNum = BDMulNum1.multiply(BDMulNum2).doubleValue();
109         return mulNum;
110     }
111     public static void main(String[] args){
112         double num = 12345.00678;
113         Num2Rmb num2rmb = new Num2Rmb();
114         double[] dividenum = num2rmb.numberLength(num);
115         System.out.println("整数部分位数:"+dividenum[0]+"\n整数部分为:"+dividenum[1]+"\n小数部分位数为:"+dividenum[2]+"\n小数部分为:"+dividenum[3]);
116         String ans = num2rmb.numToRMB(num);
117         System.out.println("整数部分RMB读法:"+ans);
118     } 
119 }
120 
121     /**输出为
122      * 整数部分位数:5.0
123      * 整数部分为:12345.0
124      * 小数部分位数为:5.0
125      * 小数部分为:0.00678
126      * 整数部分RMB读法:壹万贰千叁百肆十伍
127      */

  总结:

  1、如果要得到整数部分和小数部分的位数,完全可以先转化成String类型,然后用stringNum.length()来得到字符串的长度。整数部分字符串的长度即整数部分的位数,小数部分字符串的长度减2即是小数部分的位数。

  2、代码只实现了5位以内的数的转换。如果是更多位的数(如:123 456 567),就要更复杂一些。

 

posted on 2016-09-22 18:00  追雨的BigMouse  阅读(140)  评论(0)    收藏  举报