需要清楚的是 基础数字所对应的大写、数字所在位置的量级、金额所对应的单位
一开始学习数字时
个 十 百 千
万 十万 百万 千万
亿 十亿 百亿 千亿
主要思路是:
- 将数字分为整数部分和小数部分分别处理
- 对于数字处理从前往后走,一个一个往后加所以先处理整数再处理小数
- 处理时都需要知道数字所对应的大写
- 整数处理时需要先知道是哪个 基础计数 然后是 量级
- 小数部分直接是 金额单位 从前往后加上就好
代码如下:
function convertCurrency(money) {
// 定义汉字的数组
var cnNums = new Array(
"零",
"壹",
"贰",
"叁",
"肆",
"伍",
"陆",
"柒",
"捌",
"玖"
);//存储数字的大写 从零开始 是因为index从0开始计数
var cnIntRadice = new Array("", "拾", "佰", "仟");//基础计数
var cnIntUnits = new Array("", "万", "亿", "兆");// 量级
var cnDecUnits = new Array("角", "分", "毫", "厘");//小数位的金额单位
var cnInteger = "整";
var cnIntLast = "元";
var maxNum = 999999999999999.9999;
var integerNum;//存储金额 的整数部分
var decimalNum;//存储金额 的小数部分
var chineseStr = "";
var parts;//存储金额 整数部分和小数部分的数组
if (money == "") {//金额为‘’时返空
return "";
}
money = parseFloat(money);
if (money >= maxNum) {//金额大于最大金额返空
return "";
}
if (money == 0) {//金额为零时 直接返回 零元整
chineseStr = cnNums[0] + cnIntLast + cnInteger;
return chineseStr;
}
money = money.toString(); // 转换为字符串
if (money.indexOf(".") == -1) {//金额为整数时
integerNum = money;
decimalNum = "";
} else {
parts = money.split(".");
integerNum = parts[0];
decimalNum = parts[1].substr(0, 4);//小数位计数单位 常用 角分毫厘 四个就到厘够用了
}
if (parseInt(integerNum, 10) > 0) {//整数化为 十进制整数 大于零
var zeroCount = 0;// 金额里的数字 0
var IntLen = integerNum.length;//整数数字的长度有多长
for (var i = 0; i < IntLen; i++) {
var n = integerNum.substr(i, 1);//截出i的这一项
var p = IntLen - i - 1;//对应下标 i后面还有几位没有处理
var q = p / 4;//i 后面有几个 四位 看能不能用上仟以上的计量
var m = p % 4;//取余 四个为一组 剩下的余数 就是 当前这一项 所要从 cnIntRadice 个十百千 所对应的是十分位还是百分位还是千分位
if (n == "0") {
zeroCount++;
} else {
if (zeroCount > 0) {//每次循环到这里发现上一项是零 先给大写字符串加个零 再把 记录金额0的清空一下
chineseStr += cnNums[0];
}
zeroCount = 0; // 归零
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];//数字所对应的大写+数字多对应的基础计数
}
if (m == 0 && zeroCount < 4) {//m为0没有余数表示i项之后 要么少于四位 要么有多个四位
chineseStr += cnIntUnits[q];//q为1的话表示i项之后还有1组四位 当前的i项在 万 级别
}
}
chineseStr += cnIntLast;//加上 单位元
}
if (decimalNum != "") {//小数部分不为空
var decLen = decimalNum.length;//小数部分长度
for (var i = 0; i < decLen; i++) {
var n = decimalNum.substr(i, 1);//截出i的这一项
if (n != "0") {//这个数字不等于零时
chineseStr += cnNums[Number(n)] + cnDecUnits[i];//先匹配数字的金额大写再匹配金额单位
}
}
}
if (chineseStr == "") {//化为金额大写的字段为空时 直接 零元整
chineseStr += cnNums[0] + cnIntLast + cnInteger;
} else if (decimalNum == "") {
chineseStr += cnInteger;//+整字
}
return chineseStr;
}
复习点:
一、parseInt
1、定义
parseInt()
函数可解析一个字符串,并返回一个整数。
当参数radix
的值为 0,或没有设置该参数时,parseInt()
会根据string
来判断数字的基数。
当忽略参数
radix
, JavaScript 默认数字的基数如下:
- 以 “0x” 开头:parseInt() 会把 string 的 其余部分解析为十六进制的整数 。
- 以 0 开头:那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
- 以 1 ~ 9 的数字开头:parseInt() 将把它解析为十进制的整数。
2、语法
parseInt(string, radix)
- string 必需。要被解析的字符串。
- radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
这里主要需要注意的是第二个参数,数字的基数,很多时候都是直接parseInt(‘xxx’)上面在处理时之所以会特意加一下10作为基数是因为新旧浏览器的ECMAScript版本问题 (ECMAScript版本小于ECMAScript 5,当字符串以"0"开头时默认使用八进制,ECMAScript 5使用的是十进制)
3、注意事项
- 字符串中若包含了多个数字只会返回第一个数字。
- 开头和结尾允许有空格
- 如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。
- 在字符串以"0"为开始时旧的浏览器默认使用八进制基数。ECMAScript 5,默认的是十进制的基数。
二、substr()
1、定义
substr() 方法可在字符串中抽取从 开始 下标开始的指定数目的字符。
提示: substr() 的参数指定的是子串的开始位置和长度,因此它可以替代 substring() 和 slice() 来使用。
在 IE 4 中,参数 start 的值无效。在这个 BUG 中,start 规定的是第 0 个字符的位置。在之后的版本中,此 BUG 已被修正。
ECMAscript 没有对该方法进行标准化,因此反对使用它。
上面方法里面截取时用integerNum.substr(i, 1)
就很好理解了,从第i
项开始截取一个出来,不就是把第i
项截出来
2、语法
string.substr(start,length)
- start 必需。要抽取的子串的起始下标。必须是数值。
如果是负数,那么该参数声明从字符串的尾部开始算起的位置。也就是说,-1 指字符串中最后一个字符,-2 指倒数第二个字符,以此类推。
- length 可选。子串中的字符数。必须是数值。
如果省略了该参数,那么返回从 stringObject 的开始位置到结尾的字串。
3、注意
- substr() 方法不会改变源字符串。
三、取余%
取余%是一种数学运算,符号为%。它表示用一个数除以另一个数,然后取余数作为结果。例如,13%7 的结果就是6,因为13除以7余6。
在C语言和其他编程语言中,取余运算符通常用于计算两个数之间的余数,也可以用于进行一些简单的数学运算,如检查一个数是否为偶数或3的倍数。
需要注意的是,取余运算符的左右操作数必须是整数。在编程中,使用取余运算符时需要特别注意数据类型和溢出问题。