将一个数转化为中文金额的大写方式(有详细的解题步骤)

  1 /*
  2  * 程序目的: 从命令行输入一个数,并将其转化为中文金额的大写方式
  3  * 思路:
  4  * 所需对象:用到两个数组,一个存中文大写的数字,一个存金额单位;
  5  *          为了保持精度的相对准确,用到BigDecimal类;(不懂的朋友,上网一查就知道了);
  6  *          我这里用了StringBuilder类来存转化后的结果;(其实用String,StringBuffer都可以)
  7  * 过程:输入一个double类型的数———>转化为BigDecimal类的对象———>四舍五入后转化为long类型的数;
  8  *     先判断一下小数部分出现的特殊情况;
  9  *     统一处理数字;(每次取一位【用%10的方法】,通过和预先设置好的数组对应的方式来填充数据)
 10  *     输出最终的结果;
 11  * 难点:就零的处理;
 12  *
 13  * 1、阿拉伯数字中间有“0”时,中文大写要写“零”字,如¥1409.50应写成人民币壹仟肆佰零玖元伍角;
 14   2、阿拉伯数字中间连续有几个“0”时、中文大写金额中间可以只写一个“零”字,如¥6007.14应写成人民币陆仟零柒元壹角肆分。
 15   3、阿拉伯金额数字万位和元位是“0”,或者数字中间连续有几个“0”,万位、元位也是“0”但千位、角位不是“0”时,中文大写金额中可以只写一个零字(我这这里用的就是这种),也           可以不写“零”字,如¥1680.32应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分。又如¥107000.53应写成人民币壹拾万柒仟元零伍角叁分,或          者写成人民币壹拾万零柒仟元伍角叁分。
 16   4、阿拉伯金额数字角位是“0”而分位不是“0”时,中文大写金额“元”后面应写“零”字,如¥16409.02应写成人民币壹万陆仟肆佰零玖元零贰分,又如¥325.04应写成人民币叁佰贰拾           伍元零肆分。
 17  *
 18  * 方法:分情况处理;
 19  * 注:其实可以更加简洁写,但是为了看的更清楚,更加具有良好的编程习惯;故有些写的“啰嗦”,请见谅!
 20  *       若发现我的程序有不妥之处,还望评论指正,共同学习;
 21  */
 22
 23 import java.math.BigDecimal;
 24 import java.util.Scanner;
 25
 26 public class NumToCn {
 27
 28     //这里使用String, StringBuffer其实都可以;但从可变长度和单线程方面考虑,StringBuilder较为合适;
 29     private static StringBuilder sb = new StringBuilder();
 30
 31     private static final String[] CN_NUMBER = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
 32     private static final String[] CN_UNIT  = { "分", "角", "圆","拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾", "佰",                                                  "仟", "顺" };
 33
 34     //一些额外附加的字符
 35     private static final String CN_NEGATIVE = "负";
 36     private static final String CN_FULL = "整";
 37     private static final String CN_ZERO_FULL = "零圆整";
 38     private static final int PERCISION = 2; // 精度
 39
 40     public static String numToCn (BigDecimal numOfMoney) {
 41
 42         //当此 BigDecimal 的值为负、零或正时,返回 -1、0 或 1。
 43         int signum = numOfMoney.signum();
 44
 45         //若输入为0,输出零圆整;
 46         if(signum == 0) {
 47             return CN_ZERO_FULL;
 48         }
 49
 50         //对金额进行四舍五入转化为long类型的整数;先将数的小数点向右移两位,然后在四舍五入,取绝对值,最后将它转换为长整型;
 51         long number = numOfMoney.movePointRight(PERCISION).setScale(0, BigDecimal.ROUND_HALF_UP).abs().longValue();
 52         int numIndex = 0; //记录数字的个数;
 53         boolean getZero = false;
 54 /*
 55  * 思路:要先判断一下小数部分的具体情况;究其根本是因为:小数部分和整数部分在处理“0”的问题上略有不同;避免出现如图1所示的情况;
 56  */
 57         //得到小数部分(小数点后两位);
 58         long scale = number % 100;
 59         if(scale == 0) { //若小数部分为"00"时的情况;骚年,不要忘了在最后追加特殊字符:整
 60             numIndex += 2;
 61             getZero = true;
 62             number /= 100;  // 从number去掉为0数;
 63             sb.append(CN_FULL);
 64         } else if(scale % 10 == 0){ //若小数部分为"*0"时的情况;
 65             numIndex += 1;
 66             getZero = true;
 67             number /= 10;// 从number去掉为0数;
 68         }
 69
 70         //排除上述两种小数部分的特殊情况,则对小数和整数的处理就是一样一样一样地了!
 71         while(true) {
 72             //循环结束条件;
 73             if(number <= 0){
 74                 break;
 75             }
 76
 77             //每次通过取余来得到最后一位数;
 78             int numUnit = (int)(number % 10);
 79             if(numUnit != 0){
 80                 sb.insert(0, CN_UNIT[numIndex]);  //先添加单位
 81                 sb.insert(0, CN_NUMBER[numUnit]); //在添加根据数字值来对应数组中的中文表述;
 82                 getZero = false; //表明当前数不是0;
 83             }
 84             else {
 85                 //意思是它的上一次的数不是零,那么打印出零;
 86                 if(!getZero) {
 87                     sb.insert(0, CN_NUMBER[numUnit]);
 88                 }
 89                 //若角分位为零,那么打印零;
 90                 if(numIndex == 2) {
 91                      if(number > 0) {
 92                          sb.insert(0, CN_UNIT[numIndex]);
 93                      }
 94                 } else if((numIndex - 2) % 4 == 0 && number % 1000 !=0 ) { //第一个条件是为了每隔4位,打印“圆,万,亿”;第二个条件是为了避免出现如图3的情况;
 95                     sb.insert(0, CN_UNIT[numIndex]);
 96                 }
 97                 getZero = true; //将其置为true,那么如果下一位还是0,也不会再打印一遍‘零‘;避免出现图2的情况;
 98             }
 99
100          // 从number每次都去掉最后一个数
101             number  = number / 10;
102             numIndex++;
103         }
104
105         // 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
106         if(signum == -1) {
107             sb.insert(0, CN_NEGATIVE);
108         }
109
110         return sb.toString();
111     }
112
113
114     public static void main(String[] args) {
115         Scanner scan = new Scanner(System.in);
116         double money =  scan.nextDouble();
117         BigDecimal numOfMoney = new BigDecimal(money);
118         String s = NumToCn.numToCn(numOfMoney);
119         System.out.println(s);
120     }
121
122 }

图一:

图二:

图三:上边数是100000000;因为是测试时用的,所以会是图中所示,不用纠结;

时间: 2024-08-08 03:47:35

将一个数转化为中文金额的大写方式(有详细的解题步骤)的相关文章

将一个数转化为二进制后,求其中1的个数 C++

#include <iostream>using namespace std;int func(int x){ int count=0; while(x) { x=x&(x-1);//与的次数就是包含1的个数 count++; } return count;} void main(){ int x; cin>>x; cout<<func(x)<<endl; }

java数字金额转化为中文金额

public static String digitUppercase(double n){String fraction[] = {"角", "分"};String digit[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", &quo

递归 将一个十进制数转化为任意进制字符串

Create All kinds of guns. 设计重点: 1 基类作接口 2 继承类是各种不同的类 3 构建工厂类,然后根据需要创造不同的类,可以传入关键字,或者索引等. #pragma once #include <string> #include <iostream> using namespace std; //Base class class Gun { public: virtual string description() { return "Gener

【PDF单页转化为图片输出 注意:英文或图片类的PDF可转化,中文抛异常】

1 public static void main(String[] args) throws IOException 2 { 3 /** 4 * PDF单页转化为图片输出 注意:英文或图片类的PDF可转化,中文抛异常 5 */ 6 PDDocument doc; 7 try 8 { 9 String inputFile = "F:\\java56班\\eclipse-SDK-4.2-win32\\iText入门基础教程[2].pdf"; 10 String imagepath = &

BPM实例分享——金额规则大写

金额规则大写 在涉及金额的流程中经常会遇到需要大写金额数据与小写金额匹配,如何实现输入数字后自动转换呢? 初级用法: 1.在默认表单基本属性javascript 中增加如下金额转换方法 /** 数字金额大写转换(可以处理整数,小数,负数) */ function chineseNumber(dValue) { var maxDec = 2; // 验证输入金额数值或数值字符串: dValue = dValue.toString().replace(/,/g, ""); dValue =

js金额转大写数字

//金额转大写数字 const intToChinese = money => { //汉字的数字 let cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'); //基本单位 let cnIntRadice = new Array('', '拾', '佰', '仟'); //对应整数部分扩展单位 let cnIntUnits = new Array('', '万', '亿', '兆'); //对应小数部分单位

PHP实现数字金额转中文金额

 解决发票系统中,发票单上需要填写中文金额的问题:  function ToChineseNum($num) {         $zh_num = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];         $zh_unit = ['分', '角', '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟'];         if (!is_numeric(str_repl

输入的数转化为二进制序列,并统计序列中1的个数

★输入的数转化为二进制序列,并统计序列中1的个数 描述:普通的模除取余后数直接除二的办法易于理解,但是对于输入的数只限于正数和零,对于负数则不适应,所以采用与后移位的方法以此来扩大数的输入范围. #include<stdio.h> int main() { int m,b,c,i; int count = 0; char a[32]; printf("请输入一个数:\n"); scanf("%d", &m); for (i = 0; i <

【c语言】将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数

// 将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数 #include <stdio.h> // 从原数拿出最低位,放到mid中,mid左移,原数右移 int reverse(int a) { int mid = 0; int bit; int n = 31; for (; n > 0; --n) { bit = a & 1; mid |= bit; mid <<= 1; a >>= 1; } return mid; } int main