toTixed四舍五入不准的问题的解决

项目中发现用toFixed来实现四舍五入与预期出现了不一致的BUG,经过搜索发现tofixed不是严格按照四舍五入来的,通过重写原型方法的方式解决了该问题,将修改方法记录如下方便之后使用:

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
Number.prototype.toFixed = function(len) {
if (len > 20 || len < 0) {
throw new RangeError('toFixed() digits argument must be between 0 and 20')
}
// .123转为0.123
var number = Number(this)
if (isNaN(number) || number >= Math.pow(10, 21)) {
return number.toString()
}
if (typeof len === 'undefined' || len === 0) {
return Math.round(number).toString()
}
var result = number.toString()
var numberArr = result.split('.')

if (numberArr.length < 2) {
// 整数的情况
return padNum(result)
}
var intNum = numberArr[0] // 整数部分
var deciNum = numberArr[1] // 小数部分
var lastNum = deciNum.substr(len, 1) // 最后一个数字

if (deciNum.length === len) {
// 需要截取的长度等于当前长度
return result
}
if (deciNum.length < len) {
// 需要截取的长度大于当前长度 1.3.toFixed(2)
return padNum(result)
}
// 需要截取的长度小于当前长度,需要判断最后一位数字
result = intNum + '.' + deciNum.substr(0, len)
if (parseInt(lastNum, 10) >= 5) {
// 最后一位数字大于5,要进位
var times = Math.pow(10, len) // 需要放大的倍数
var changedInt = Number(result.replace('.', '')) // 截取后转为整数
changedInt++ // 整数进位
changedInt /= times // 整数转为小数,注:有可能还是整数
result = padNum(changedInt + '')
}
return result
// 对数字末尾加0
function padNum(num) {
var dotPos = num.indexOf('.')
if (dotPos === -1) {
// 整数的情况
num += '.'
for (var i = 0; i < len; i++) {
num += '0'
}
return num
} else {
// 小数的情况
var need = len - (num.length - dotPos - 1)
for (var j = 0; j < need; j++) {
num += '0'
}
return num
}
}
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!