• js 四舍五入实现


    js Number.prototype.toFixed 进行的舍入的算法没研究明白,应该不是四舍六入五成双,当然也不是四舍五入

    下面是chrome与excel的对比

    修改完之后的结果

    对于“问题数据”的测试

    代码如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<script type="text/javascript">
    		Number.prototype.toFixed2 = function (decimal) {
    		  // console.log(this, decimal)
    		  if (Number(decimal) < 0 && Number(decimal) > 100) {
    		    return RangeError('toFixed() digits argument must be between 0 and 100');
    		  }
    		  // 按小数点分割,得到整数位及小数位
    		  // 按保留小数点位数分割小数位,得到需保留的小数位
    		  // 将需保留的小数位与整数位拼接得到四舍五入之前的结果
    		  // 对需四舍五入的小数最大一位数进行四舍五入,如果大于等于5则进位flag为1,否则为0
    		  // 对四舍五入之前的结果+进位flag进行四舍五入得到最终结果
    
    		  // 分割整数与小数
    		  let cutArr = this.toString().split('.');
    		  // 小数部分根据要保留的小数确定,如果小数部分长度小于要保留的精度缺失部分用0补全
    		  let decimalStr = cutArr[1].length > decimal ? cutArr[1] : cutArr[1] + new Array(decimal - cutArr[1].length).fill('0');
    		  // 是否进位
    		  const plus = decimalStr.slice(decimal, (decimal+1)) >= 5 ? 1 : 0;
    		  // 未四舍五入之前,(处理保留0位小数)
    		  let mainArr = (cutArr[0] + (decimal > 0 ? ('.' + decimalStr.slice(0, decimal)) : ('' + decimalStr.slice(0, decimal)))).split('');
    		  // 要输出的结果最后一位+是否要进位,
    		  mainArr[mainArr.length - 1] = Number(mainArr[mainArr.length - 1]) + plus;
    		  mainArr.reverse();
    		  // 如果加完是10则向前进一位,否则直接输出
    		  if (plus && mainArr[0] > 9) {
    		    for (let i = 0; i < mainArr.length; i++) {
    		      if (mainArr[i] > 9) {
    		        if (mainArr[i + 1] != undefined && mainArr[i + 2] != undefined) {
    		          if (mainArr[i + 1] === '.') {
    		            mainArr[i + 2] = Number(mainArr[i + 2]) + 1;
    		          } else {
    		            mainArr[i + 1] = Number(mainArr[i + 1]) + 1;
    		          }
    		        }
    		        mainArr[i] = 0
    		      }
    		    }
    		  }
    		  return mainArr.reverse().join().replace(/,/g, '')
    		}
    		// 测试
    		// 
    		console.log('四舍六入五成双测试')
    		console.group();
    		console.log('(9.8350).toFixed(2)',(9.8350).toFixed(2),'(9.8350).toFixed(2)',(9.8350).toFixed2(2));
    		console.log('(1.335).toFixed(2)',(1.335).toFixed(2),'(1.335).toFixed(2)',(1.335).toFixed2(2));
    		console.log('(9.8250).toFixed(2)',(9.8250).toFixed(2),'(9.8250).toFixed(2)',(9.8250).toFixed2(2));
    		console.groupEnd();
    		console.log("四舍六入五成双测试");
    		console.log('数值计算测试')
    		console.group();
    		console.log('(0.1+0.2).toFixed(10)',(0.1+0.2).toFixed(10),'(0.1+0.2).toFixed(10)',(0.1+0.2).toFixed2(10));
    		console.log('(0.1+0.2).toFixed(2)',(0.1+0.2).toFixed(2),'(0.1+0.2).toFixed(2)',(0.1+0.2).toFixed2(2));
    		console.log('(2.0115 * 1000).toFixed(0)',(2.0115 * 1000).toFixed(0),'(2.0115 * 1000).toFixed(0)',(2.0115 * 1000).toFixed2(0));
    		console.groupEnd();
    		console.log("数值计算测试");
    	</script>
    </body>
    </html>
    

      补:

    四舍六入五成双

    具体规则如下

      (1)被修约的数字小于5时,该数字舍去;

      (2)被修约的数字大于5时,则进位;

      (3)被修约的数字等于5时,要看5前面的数字,若是奇数则进位,若是偶数则将5舍掉,即修约后末尾数字都成为偶数;若5的后面还有不为“0”的任何数,则此时无论5的前面是奇数还是偶数,均应进位。

      举例:

        9.8249=9.82, 9.82671=9.83

        9.8350=9.84, 9.8351 =9.84

        9.8250=9.82, 9.82501=9.83

  • 相关阅读:
    Embeded Linux 之 PHY
    Embeded Linux之网络子系统
    语言之内联函数
    Embeded Linux之海思UART
    Windows 之samba问题
    Embeded linux 之 CIFS 文件操作源码分析
    zookeeper 都有哪些使用场景?
    如何保证分布式系统中接口调用的顺序性?
    分布式系统中接口的幂等性该如何保证?比如不能重复扣款?
    Redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗?
  • 原文地址:https://www.cnblogs.com/zhangtao1990/p/9371978.html
Copyright © 2020-2023  润新知