1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
const operationObj = {
/**
* 处理传入的参数,不管传入的是数组还是以逗号分隔的参数都处理为数组
* @param args
* @returns {*}
*/
getParams(args) {
return Array.prototype.concat.apply([], args);
},
/**
* 获取每个数的乘数因子,根据小数位数计算
* 1.首先判断是否有小数点,如果没有,则返回1;
* 2.有小数点时,将小数位数的长度作为Math.pow()函数的参数进行计算
* 例如2的乘数因子为1,2.01的乘数因子为100
* @param x
* @returns {number}
*/
multiplier(x) {
let parts = x.toString().split('.');
return parts.length < 2 ? 1 : Math.pow(10, parts[1].length)
},
/**
* 获取多个数据中最大的乘数因子
* 例如1.3的乘数因子为10,2.13的乘数因子为100
* 则1.3和2.13的最大乘数因子为100
* @returns {*}
*/
correctionFactor() {
let args = Array.prototype.slice.call(arguments)
let argArr = this.getParams(args);
return argArr.reduce((accum, next) => {
let num = this.multiplier(next);
return Math.max(accum, num)
}, 1)
},
/**
* 加法运算
* @param args
* @returns {number}
*/
add(...args) {
let calArr = this.getParams(args);
// 获取参与运算值的最大乘数因子
let corrFactor = this.correctionFactor(calArr)
let sum = calArr.reduce((accum, curr) => {
// 将浮点数乘以最大乘数因子,转换为整数参与运算
return accum + Math.round(curr * corrFactor)
}, 0)
// 除以最大乘数因子
return sum / corrFactor;
},
/**
* 减法运算
* @param args
* @returns {number}
*/
subtract(...args) {
let calArr = this.getParams(args);
let corrFactor = this.correctionFactor(calArr);
let diff = calArr.reduce((accum, curr, curIndex) => {
// reduce()函数在未传入初始值时,curIndex从1开始,第一位参与运算的值需要
// 乘以最大乘数因子
if(curIndex === 1) {
return Math.round(accum * corrFactor) - Math.round(curr * corrFactor)
}
// accum 作为上一次运算的结果,就无须再乘以最大因子
return Math.round(accum) - Math.round(curr * corrFactor)
})
// 除以最大乘数因子
return diff / corrFactor;
},
/**
* 乘法运算
* @param args
* @returns {*}
*/
multiply(...args) {
let calArr = this.getParams(args);
let corrFactor = this.correctionFactor(calArr)
calArr = calArr.map(item => {
// 乘以最大乘数因子
return item * corrFactor
})
let multi = calArr.reduce((accum, curr) => {
return Math.round(accum) * Math.round(curr)
}, 1);
// 除以最大乘数因子
return multi / Math.pow(corrFactor, calArr.length);
},
/**
* 除法运算
* @param args
* @returns {*}
*/
divide(...args) {
let calArr = this.getParams(args);
let quotient = calArr.reduce((accum, curr) => {
let corrFactor = this.correctionFactor(accum, curr);
// 同时转换为整数参与运算
return Math.round(accum * corrFactor) / Math.round(curr * corrFactor)
})
return quotient;
}
}
console.log(operationObj.add(0.1, 0.7)); // 0.8
console.log(operationObj.subtract(0.3, 0.2)); // 0.1
console.log(operationObj.multiply(0.7, 180)); // 126
console.log(operationObj.divide(0.3, 0.1)); // 3