UNPKG

6.49 kBJavaScriptView Raw
1if (!window._seeds_lang) window._seeds_lang = {}; // 国际化数据
2/* -------------------
3解决加减乘除精度
4------------------- */
5Math.Calc = function () {
6 /* -----------------------------------------------------
7 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
8 @param (argNum: {number} 小数, argDigits: {number} 截取小数位, round: {bool} 是否四舍五入 默认为true)
9 @return result {times:100, num: 314}
10 ----------------------------------------------------- */
11 function toInteger(argNum, argDigits, round) {
12 var result = { times: 1, num: 0 };
13 var argNumStr = argNum + '';
14 if (argNumStr.indexOf('.') === -1) {
15 result.num = argNum;
16 return result;
17 }
18 var digits = isNaN(argDigits) ? argNumStr.substr(argNumStr.indexOf('.') + 1).length : argDigits; // 小数位数
19 var times = Math.pow(10, digits);
20 var num = parseInt(Math.abs(argNum) * times + (round === false ? 0 : 0.5), 10); // 转成整数,并且小数位四舍五入
21 var isNegative = argNum < 0; // 是否是负数
22 result.times = times;
23 result.num = isNegative ? -num : num;
24 return result;
25 }
26
27 /* -----------------------------------------------------
28 核心方法,实现加减乘除运算,确保不丢失精度
29 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)
30 @param a {number} 运算数1
31 @param b {number} 运算数2
32 @param digits {number} 精度,保留的小数点数,比如 2, 即保留为两位小数
33 @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide)
34 ----------------------------------------------------- */
35 function operation(a, b, digits, op) {
36 var o1 = toInteger(a);
37 var o2 = toInteger(b);
38 var n1 = o1.num;
39 var n2 = o2.num;
40 var t1 = o1.times;
41 var t2 = o2.times;
42 var max = t1 > t2 ? t1 : t2;
43 var result = null;
44 switch (op) {
45 case 'add':
46 if (t1 === t2) {
47 // 两个小数位数相同
48 result = Number(n1) + Number(n2);
49 } else if (t1 > t2) {
50 // o1 小数位 大于 o2
51 result = Number(n1) + Number(n2 * (t1 / t2));
52 } else {
53 // o1 小数位 小于 o2
54 result = Number(n1 * (t2 / t1)) + Number(n2);
55 }
56 result = result / max;
57 break;
58 case 'subtract':
59 if (t1 === t2) {
60 result = n1 - n2;
61 } else if (t1 > t2) {
62 result = n1 - n2 * (t1 / t2);
63 } else {
64 result = n1 * (t2 / t1) - n2;
65 }
66 result = result / max;
67 break;
68 case 'multiply':
69 result = n1 * n2 / (t1 * t2);
70 break;
71 case 'divide':
72 result = n1 / n2 * (t2 / t1);
73 break;
74 default:
75 result = 0;
76 }
77 if (digits && !isNaN(digits)) {
78 // 精度设置
79 return result.toFixed(digits);
80 }
81 return result;
82 }
83
84 // 加减乘除的四个接口
85 function add(a, b, digits) {
86 return operation(a, b, digits, 'add');
87 }
88 function subtract(a, b, digits) {
89 return operation(a, b, digits, 'subtract');
90 }
91 function multiply(a, b, digits) {
92 return operation(a, b, digits, 'multiply');
93 }
94 function divide(a, b, digits) {
95 return operation(a, b, digits, 'divide');
96 }
97 // toFixed 修复旧浏览器0.07.toFixed(1) => 0.0不会四舍五入的问题
98 function toFixed(argNum, argDigits, fixed, round) {
99 var result = toInteger(argNum, argDigits, round);
100 if (fixed) return (result.num / result.times).toFixed(argDigits);
101 return result.num / result.times;
102 }
103 // 转换为千分位字符
104 function toThousandth(num) {
105 if (!num) return '0';
106 var sExpr = /^(\d+)((\.\d+)?)$/;
107 var n1 = num.toString().replace(sExpr, function (s, s1, s2) {
108 var reExpr = /\d{1,3}(?=(\d{3})+$)/g;
109 return s1.replace(reExpr, '$&,') + s2;
110 });
111 return n1;
112 }
113 // 矫正数字, 常用于输入过程中矫正, 可以为空串
114 function correctNumber(argNumstr, options) {
115 var max = options.max,
116 min = options.min,
117 digits = options.digits,
118 maxLength = options.maxLength,
119 required = options.required,
120 onError = options.onError;
121
122 if (argNumstr === '' || isNaN(argNumstr) || min - max >= 0) {
123 // 非空校验
124 if (required) return min ? '' + min : '0';
125 return '';
126 }
127 var value = String(argNumstr || '');
128 // 最大值
129 if (!isNaN(max) && value - max > 0) {
130 // callback onError
131 if (onError) onError({ errMsg: window._seeds_lang['hint_cannot_be_greater_than'] || '不能大于' + max });
132 return '' + max;
133 }
134 // 最小值
135 if (!isNaN(min) && value - min < 0) {
136 // callback onError
137 if (onError) onError({ errMsg: window._seeds_lang['hint_cannot_be_less_than'] || '不能小于' + min });
138 return '' + min;
139 }
140 // 截取小数位数
141 if (!isNaN(digits)) {
142 console.log(digits);
143 if (value.indexOf('.') !== -1 && digits - 0 >= 0 && digits.toString().indexOf('.') === -1) {
144 if (digits - 0 === 0) {
145 // 整数
146 value = value.substring(0, value.indexOf('.'));
147 } else {
148 // 小数
149 value = value.substring(0, value.indexOf('.') + Number(digits) + 1);
150 }
151 }
152 }
153 // 最大长度限制
154 if (maxLength && value && value.length > maxLength) {
155 value = value.substring(0, maxLength);
156 }
157 // 转成Number类型, 防止001的情况, 小数不能转, 因为有可能是1.0001的情况
158 if (value.indexOf('.') === -1) {
159 return '' + Number(value);
160 }
161 return '' + value;
162 }
163 // 矫正手机号码, 用于输入过程中矫正
164 function correctPhone(argPhone, options) {
165 var onError = options.onError;
166
167 var value = argPhone;
168 // 如果输入的不是一个正整数,则转为正整数
169 if (isNaN(value)) {
170 var result = value.match(/[0-9]{1,}/);
171 if (result) value = result[0];else value = '';
172 // callback onError
173 if (onError) onError({ errMsg: window._seeds_lang['hint_must_number'] || '必须要输入数字哦' });
174 }
175 return value;
176 }
177 // exports
178 return {
179 add: add, // 解决运算中1.22+1不等于2.22的问题
180 subtract: subtract, // 解决运算中1.22-1不等于0.22的问题
181 multiply: multiply,
182 divide: divide,
183 toFixed: toFixed,
184 toThousandth: toThousandth,
185 correctNumber: correctNumber,
186 correctPhone: correctPhone
187 };
188}();
\No newline at end of file