一、把阿拉伯数字转换成中文人民币读法
要求:
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),就要更复杂一些。
浙公网安备 33010602011771号