首页 > 其他分享 >把输入的金额转换为汉语中人民币的大写

把输入的金额转换为汉语中人民币的大写

时间:2023-06-27 10:03:38浏览次数:23  
标签:return String int number 大写 length 汉语 str 输入

方法1

    /**
     * 汉语中数字大写
     */
    private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
    /**
     * 汉语中货币单位大写,这样的设计类似于占位符
     */
    private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰",
            "仟", "亿", "拾", "佰", "仟", "兆", "拾", "佰", "仟" };
    /**
     * 特殊字符:整
     */
    private static final String CN_FULL = "整";
    /**
     * 特殊字符:负
     */
    private static final String CN_NEGATIVE = "负";
    /**
     * 金额的精度,默认值为2
     */
    private static final int MONEY_PRECISION = 2;
    /**
     * 特殊字符:零元整
     */
    private static final String CN_ZEOR_FULL = "零元" + CN_FULL;

    /**
     * 把输入的金额转换为汉语中人民币的大写
     * 
     * @param amount 输入的金额
     * @return 对应的汉语大写
     */
    public static String number2CN(BigDecimal amount) {
        if (null == amount) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        // -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
        // positive.
        // 判断金额正、负还是零
        int signum = amount.signum();
        // 零元整的情况
        if (signum == 0) {
            return CN_ZEOR_FULL;
        }
        // 这里会进行金额的四舍五入
        long number = amount.movePointRight(MONEY_PRECISION).setScale(0, 4).abs().longValue();
        // 得到小数点后两位值
        long scale = number % 100;
        int numUnit = 0;
        int numIndex = 0;
        boolean getZero = false;
        // 判断最后两位数,一共有四中情况:00 = 0, 01 = 1, 10, 11
        if (!(scale > 0)) {
            numIndex = 2;
            number = number / 100;
            getZero = true;
        }
        if ((scale > 0) && (!(scale % 10 > 0))) {
            numIndex = 1;
            number = number / 10;
            getZero = true;
        }
        int zeroSize = 0;
        while (true) {
            if (number <= 0) {
                break;
            }
            // 每次获取到最后一个数
            numUnit = (int) (number % 10);
            if (numUnit > 0) {
                if ((numIndex == 9) && (zeroSize >= 3)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
                }
                if ((numIndex == 13) && (zeroSize >= 3)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
                }
                sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                getZero = false;
                zeroSize = 0;
            } else {
                ++zeroSize;
                // 个位上无需添加零
                if (numIndex != 2 && !(getZero)) {
                    sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                }
                if (numIndex == 2) {
                    if (number > 0) {
                        sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                    }
                } else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                }
                getZero = true;
            }
            // 让number每次都去掉最后一个数
            number = number / 10;
            ++numIndex;
        }
        // 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
        if (signum == -1) {
            sb.insert(0, CN_NEGATIVE);
        }
        // 输入的数字小数点后两位为"00"的情况,则要在最后追加特殊字符:整
        if (!(scale > 0)) {
            sb.append(CN_FULL);
        }
        return sb.toString();
    }

方法2

    // 大写数字
    private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
    // 整数部分的单位
    private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰",
            "仟" };
    // 小数部分的单位
    private static final String[] DUNIT = { "角", "分", "厘" };

    /**
     * 转换为大写的中文金额
     *
     * @param str 字符串类型的 金额数字
     * @return
     */
    public static String toChinese(String str) {
        // 判断输入的金额字符串是否符合要求
        if (StringUtils.isBlank(str) || !str.matches("(-)?[\\d]*(.)?[\\d]*")) {
            return "抱歉,请输入数字!";
        }

        if ("0".equals(str) || "0.00".equals(str) || "0.0".equals(str)) {
            return "零元";
        }

        // 判断金额数字中是否存在负号"-"
        boolean flag = false;
        if (str.startsWith("-")) {
            // 标志位,标志此金额数字为负数
            flag = true;
            str = str.replaceAll("-", "");
        }

        // 去掉金额数字中的逗号","
        str = str.replaceAll(",", "");
        String integerStr;// 整数部分数字
        String decimalStr;// 小数部分数字

        // 初始化:分离整数部分和小数部分
        if (str.indexOf(".") > 0) {
            integerStr = str.substring(0, str.indexOf("."));
            decimalStr = str.substring(str.indexOf(".") + 1);
        } else if (str.indexOf(".") == 0) {
            integerStr = "";
            decimalStr = str.substring(1);
        } else {
            integerStr = str;
            decimalStr = "";
        }

        // beyond超出计算能力,直接返回
        if (integerStr.length() > IUNIT.length) {
            return "超出计算能力!";
        }

        // 整数部分数字
        int[] integers = toIntArray(integerStr);
        // 判断整数部分是否存在输入012的情况
        if (integers.length > 1 && integers[0] == 0) {
            return "抱歉,输入数字不符合要求!";
        }
        // 设置万单位
        boolean isWan = isWan5(integerStr);
        // 小数部分数字
        int[] decimals = toIntArray(decimalStr);
        // 返回最终的大写金额
        String result = getChineseInteger(integers, isWan) + getChineseDecimal(decimals);
        if (flag) {
            // 如果是负数,加上"负"
            return "负" + result;
        } else {
            return result;
        }
    }

    /**
     * 将字符串转为int数组
     *
     * @param number 数字
     * @return
     */
    private static int[] toIntArray(String number) {
        int[] array = new int[number.length()];
        for (int i = 0; i < number.length(); i++) {
            array[i] = Integer.parseInt(number.substring(i, i + 1));
        }
        return array;
    }

    /**
     * 将整数部分转为大写的金额
     *
     * @param integers 整数部分数字
     * @param isWan    整数部分是否已经是达到【万】
     * @return
     */
    public static String getChineseInteger(int[] integers, boolean isWan) {
        StringBuffer chineseInteger = new StringBuffer("");
        int length = integers.length;
        if (length == 1 && integers[0] == 0) {
            return "";
        }
        for (int i = 0; i < length; i++) {
            String key = "";
            if (integers[i] == 0) {
                if ((length - i) == 13)//万(亿)
                    key = IUNIT[4];
                else if ((length - i) == 9) {//亿
                    key = IUNIT[8];
                } else if ((length - i) == 5 && isWan) {//万
                    key = IUNIT[4];
                } else if ((length - i) == 1) {//元
                    key = IUNIT[0];
                }
                if ((length - i) > 1 && integers[i + 1] != 0) {
                    key += NUMBERS[0];
                }
            }
            chineseInteger.append(integers[i] == 0 ? key : (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
        }
        return chineseInteger.toString();
    }

    /**
     * 将小数部分转为大写的金额
     *
     * @param decimals 小数部分的数字
     * @return
     */
    private static String getChineseDecimal(int[] decimals) {
        StringBuffer chineseDecimal = new StringBuffer("");
        for (int i = 0; i < decimals.length; i++) {
            if (i == 3) {
                break;
            }
            chineseDecimal.append(decimals[i] == 0 ? "" : (NUMBERS[decimals[i]] + DUNIT[i]));
        }
        return chineseDecimal.toString();
    }

    /**
     * 判断当前整数部分是否已经是达到【万】
     *
     * @param integerStr 整数部分数字
     * @return
     */
    private static boolean isWan5(String integerStr) {
        int length = integerStr.length();
        if (length > 4) {
            String subInteger = "";
            if (length > 8) {
                subInteger = integerStr.substring(length - 8, length - 4);
            } else {
                subInteger = integerStr.substring(0, length - 4);
            }
            return Integer.parseInt(subInteger) > 0;
        } else {
            return false;
        }
    }

 

标签:return,String,int,number,大写,length,汉语,str,输入
From: https://www.cnblogs.com/cool5201314/p/17507883.html

相关文章

  • js-如何设置input只能输入数字
    如何设置input只能输入数字 方法一将<input>标签中的​type​属性直接设置为​number​就可以达到只能输入数字。但是这个方式有一个缺点,它只能作用于网页端,在手机输入的话还是可以输入汉字或英文:<inputtype="number"name="">方法二还是一样在<input>标签上设置,代码如......
  • 【CSS】写一个原生的透明 input 标签输入框
    <divclass="search"> <imgsrc="@/assets/tools/search.svg"/> <inputplaceholder="搜索"@input="onSearch"v-model="searchValue"/></div>.search{ height:32px; width:204px; di......
  • 【华为机试ACM基础#02】从单向链表中删除指定值的节点(熟悉链表的输入方式,虽然说本题可
    从单向链表中删除指定值的节点输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。链表的值不能重复。构造过程,例如输入一行数据为:6212325145722则第一个参数6表示输入总共6个节点,第二个参数2表示头节点值为2,剩......
  • Pytorch | 输入的形状为[seq_len, batch_size, d_model]和 [batch_size, seq_len, d_m
    首先导入依赖的torch包。importtorch我们设:seq_len(序列的最大长度):5batch_size(批量大小):2d_model(每个单词被映射为的向量的维度):10heads(多头注意力机制的头数):5d_k(每个头的特征数):21、输入形状为:[seq_len,batch_size,d_model]input_tensor=torch.randn(5,2,10)inp......
  • Element textarea 行数限制,超过限定行数不允许输入
    代码methods:{//获取行数getRow(val){letrow=0val.split('\n').forEach(item=>{if(item.length===0){row+=1//如果一行只有回车符就是行数增加一行}else{row+=Math.ceil(item.replace(/[\u0......
  • springboot中自定义JavaBean返回的json对象属性名称大写变小写问题
    目录一、继承类二、手动添加Get方法三、@JsonProperty四、spring-bootjson(jackson)属性命名策略开发过程中发现查询返回的数据出现自定义的JavaBean的属性值大小写格式出现问题,导致前端无法接受到数据,目前有四种解决方法,根据大佬的经验之谈,前两种是最简单便捷的,后两种是比较通......
  • 油烟机语音方案:NV040D语音芯片,支持MCU输入UART指令
    随着人们生活水平的提高和厨房使用频率的增加,油烟机成为现代家庭生活中必不可少的一种家用电器,而语音智能化技术的发展也使得油烟机功能更加智能化。九芯电子的NV040D语音芯片是一种具备MCU输入UART指令功能的专业语音芯片,可以广泛应用于油烟机的语音控制领域。本文将介绍NV040D语......
  • linux下使用scp远程传输自动输入密码
    由于需要将A服务器的文件远程传输到B服务器但是scp命令每次都要手动输入密码这样脚本执行太繁琐,所以讲A服务器和B服务器互信即可,具体操作如下: 首先在A服务器配置:mkdir-p~/.sshchmod700~/.ssh 然后在~/.ssh目录生成密钥文件:cd~/.shhssh-keygen-trsa-P""......
  • 油烟机语音方案:NV040D语音芯片,支持MCU输入UART指令
    随着人们生活水平的提高和厨房使用频率的增加,油烟机成为现代家庭生活中必不可少的一种家用电器,而语音智能化技术的发展也使得油烟机功能更加智能化。九芯电子的NV040D语音芯片是一种具备MCU输入UART指令功能的专业语音芯片,可以广泛应用于油烟机的语音控制领域。本文将介绍NV040D语......
  • elementplus vue 范围输入框
    <divclass="fv-rowmb-7"><labelclass="fs-6fw-semoboldmb-2">{{t("Numberofgroups")}}</label><el-form-itemprop="formInline.group"><el-inputcl......