将数字转换为中文大写
在日常的应用中,特别是财务相关的模块,经常需要将阿拉伯数字转换为中文大写格式。本文将介绍如何使用JavaScript编写一个函数,将数字转换为对应的中文大写格式。
背景知识
中文大写数字用于避免数字在书写和打印过程中被篡改。它不仅包括0-9的中文数字,还包括对应的单位,如"拾"、“佰”、“仟”、“万”、"亿"等。此外,处理小数部分时,还需要考虑"角"和"分"单位。
实现步骤
我们将实现一个numberToChinese
函数,该函数将数字转换为中文大写格式。具体实现步骤如下:
- 定义中文数字和单位: 我们首先定义中文数字和单位的字符串数组,这些数组将用于替换数字和单位。
- 拆分整数和小数部分: 使用
split
方法将数字拆分为整数和小数部分,并处理小数部分最多保留两位。 - 处理整数部分: 遍历整数部分的每一位,根据其位置插入对应的单位,处理连续的零,确保生成正确的中文大写格式。
- 处理小数部分: 遍历小数部分的每一位,根据其位置插入对应的单位,生成小数部分的中文大写格式。
- 合并结果: 将整数部分和小数部分的结果合并,生成最终的中文大写格式。
话不多说,先将完整代码奉上,后面会进行详细的说明:
function numberToChinese(num) {
const chineseDigits = '零壹贰叁肆伍陆柒捌玖';
const chineseUnits = ['', '拾', '佰', '仟'];
const chineseBigUnits = ['', '万', '亿', '兆'];
const chineseDecimalUnits = ['角', '分'];
if (isNaN(num)) {
console.error('输入的不是有效的数字')
return '输入的不是有效的数字';
}
let [integerPart, decimalPart] = num.toString().split('.');
decimalPart = (decimalPart || '00').substring(0, 2); // 保留两位小数
const integerStr = convertIntegerPart(integerPart, chineseDigits, chineseUnits, chineseBigUnits);
const decimalStr = convertDecimalPart(decimalPart, chineseDigits, chineseDecimalUnits);
return integerStr + decimalStr;
}
function convertIntegerPart(integerPart, chineseDigits, chineseUnits, chineseBigUnits) {
if (integerPart === '0') {
return '零元';
}
const len = integerPart.length;
let result = '';
let zeroFlag = false;
for (let i = 0; i < len; i++) {
const digit = integerPart.charAt(i);
const pos = len - i - 1;
const unitIndex = pos % 4;
const bigUnitIndex = Math.floor(pos / 4);
if (digit === '0') {
zeroFlag = true;
} else {
if (zeroFlag) {
result += '零';
zeroFlag = false;
}
result += chineseDigits[digit] + chineseUnits[unitIndex];
}
if (unitIndex === 0 && bigUnitIndex > 0) {
result += chineseBigUnits[bigUnitIndex];
}
}
return result + '元';
}
function convertDecimalPart(decimalPart, chineseDigits, chineseDecimalUnits) {
if (decimalPart === '00') {
return '整';
}
let result = '';
for (let i = 0; i < decimalPart.length; i++) {
const digit = decimalPart.charAt(i);
if (digit !== '0') {
result += chineseDigits[digit] + chineseDecimalUnits[i];
}
}
return result || '整';
}
详细说明
1. 定义中文数字和单位
const chineseDigits = '零壹贰叁肆伍陆柒捌玖';
const chineseUnits = ['', '拾', '佰', '仟'];
const chineseBigUnits = ['', '万', '亿', '兆'];
const chineseDecimalUnits = ['角', '分'];
2. 拆分整数和小数部分
使用split
方法将数字拆分为整数部分和小数部分:
let [integerPart, decimalPart] = num.toString().split('.');
decimalPart = (decimalPart || '00').substring(0, 2); // 保留两位小数
3. 处理整数部分
整数部分的处理函数convertIntegerPart
通过遍历每一位数字,插入对应的中文数字和单位,并处理连续的零:
-
特殊处理零:如果整数部分是零,直接返回“零元”。
if (integerPart === '0') { return '零元'; }
-
初始化变量:获取整数部分的长度,初始化结果字符串和零标记
zeroFlag
。const len = integerPart.length; let result = ''; let zeroFlag = false;
-
循环处理每一位数字:
- 计算当前位置的单位索引
unitIndex
和大单位索引bigUnitIndex
。 - 如果当前数字是零,设置
zeroFlag
为真。 - 如果当前数字不是零:
- 如果
zeroFlag
为真,先添加一个“零”。 - 添加当前数字对应的中文字符和单位。
- 如果
- 根据单位位置添加大单位(如“万”、“亿”)。
for (let i = 0; i < len; i++) { const digit = integerPart.charAt(i); const pos = len - i - 1; const unitIndex = pos % 4; const bigUnitIndex = Math.floor(pos / 4); if (digit === '0') { zeroFlag = true; } else { if (zeroFlag) { result += '零'; zeroFlag = false; } result += chineseDigits[digit] + chineseUnits[unitIndex]; } if (unitIndex === 0 && bigUnitIndex > 0) { result += chineseBigUnits[bigUnitIndex]; } }
- 计算当前位置的单位索引
4. 处理小数部分
小数部分的处理函数convertDecimalPart
通过遍历每一位小数,插入对应的中文数字和单位:
function convertDecimalPart(decimalPart, chineseDigits, chineseDecimalUnits) {
if (decimalPart === '00') {
return '整';
}
let result = '';
for (let i = 0; i < decimalPart.length; i++) {
const digit = decimalPart.charAt(i);
if (digit !== '0') {
result += chineseDigits[digit] + chineseDecimalUnits[i];
}
}
return result || '整';
}
5. 合并结果
最后,我们将整数部分和小数部分的结果合并,生成最终的中文大写格式:
return integerStr + decimalStr;
测试示例
我们通过几个测试用例来验证我们的实现:
console.table({
11700.00: numberToChinese(11700.00),
43022.12: numberToChinese(43022.12),
1234567890.56: numberToChinese(1234567890.56),
1001: numberToChinese(1001),
0.05: numberToChinese(0.05),
0: numberToChinese(0),
});
总结
通过本文的介绍,我们实现了一个将数字转换为中文大写的JavaScript函数。在实际应用中,这个功能可以应用于财务报表、票据打印等场景。
希望这篇文章对你有所帮助。如果你有任何问题或建议,欢迎在下方留言讨论。