重写toFixed方法,实现四舍五入保留小数

思路:

首次,将数分为整数和小数部分。

其次,判断小数部分是否超出要保留的位数,如果超出,则将超出的部分作为新的小数,使用Math库中round方法去四舍五入取整得出进位(0或者1)。

最后,将此进位数加上保留的小数部分,如果结果多出位数说明小数部分需要向整数进位了,否则输出:整数+小数点+(保留的小数部分+进位数)。

  /**
   * arg以四舍五入的方式保留小数点后n位
   */
  function toFixed(arg, n) {
 	if(n == 0) {
	  return Math.round(arg)
	}
	try {
	  var d, carryD, 
	  ds = arg.toString().split('.'), // 分割整数和小数
	  len = ds[1].length
	  // arg的小数位数超出限制位数n才需要处理
	  if (len > n) {
		// 先截取前n位小数
		d = Number(ds[1].substring(0, n))
		// 舍去的小数部分是否能够进一:通过 0.[第n位小数后的数] 四舍五入取整,结果为0或1
		carryD = Math.round(Number('0.' + ds[1].substring(n, len)))
		len = (d + carryD).toString().length
		if (len > n) {
		  // 当d=9...,carryD=1,相加后就得向整数进位了,直接返回 整数部分+1
		  return Number(ds[0]) + 1
		} else if (len == n) {
		  return Number(ds[0] + '.' + (d + carryD))
		}
		// 小数以0开头要往前补0
		var b0 = '', k = 0
		while(k < n && ds[1].substring(0, ++k) == '0') {
		  b0 += '0'
		}
		return Number(ds[0] + '.' + b0 + (d + carryD))
	  }
	} catch (e) {}
	return arg
  }

 

 

toFixed方法是用来将一个数字保留指定位数的小数方法。它返回的是一个字符串形式的结果,并且如果不够指定的位数,会使用0进行补齐。然而,toFixed方法并不是以四舍五入的方式进行取舍的,而是使用银行家舍入法进行取舍的。银行家舍入法是一种四舍六入五取偶的方法。具体规则如下: - 当舍去位的数值小于5时,直接舍去。 - 当舍去位的数值大于等于6时,在舍去的同时向前进一位。 - 当舍去位的数值等于5时: - 如果5后不为空且不全为0,则在舍去的同时向前进一位。 - 如果5后为空或全为0: - 如果5前的数值为奇数,则在舍去的同时向前进一位。 - 如果5前的数值为偶数,则直接舍去。 然而,有人发现使用toFixed方法时,遇到取舍位置为5的情况时会出现问题。例如,89.115.toFixed(2)会得到89.11而不是89.12。这是因为toFixed方法在遇到5时会出现问题。为了解决这个问题,有人重写toFixed方法,使用了自定义的逻辑来进行四舍五入。具体的重写代码如下: ```javascript Number.prototype.toFixed = function(d) { var s = this + ""; if (!d) d = 0; if (s.indexOf(".") == -1) s += "."; s += new Array(d + 1).join("0"); if (new RegExp("^(-|\\+)?(\\d+(\\.\\d{0," + (d + 1) + "})?)\\d*$").test(s)) { var s = "0" + RegExp.$2, pm = RegExp.$1, a = RegExp.$3.length, b = true; if (a == d + 2) { a = s.match(/\d/g); if (parseInt(a\[a.length - 1\]) > 4) { for (var i = a.length - 2; i >= 0; i--) { a\[i\] = parseInt(a\[i\]) + 1; if (a\[i\] == 10) { a\[i\] = 0; b = i != 1; } else break; } } s = a.join("").replace(new RegExp("(\\d+)(\\d{" + d + "})\\d$"), "$1.$2"); } if (b) s = s.substr(1); return (pm + s).replace(/\.$/, ""); } return this + ""; }; ``` 这段代码重写toFixed方法,使用了自定义的逻辑来进行四舍五入。但需要注意的是,这段代码并非官方提供的方法,使用时需要谨慎。 #### 引用[.reference_title] - *1* [JavaScript toFixed()四舍五入问题](https://blog.youkuaiyun.com/qq_38877858/article/details/108111072)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [toFixed方法无法精准四舍五入的问题](https://blog.youkuaiyun.com/weixin_42597658/article/details/116535343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Homilier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值