javascript中toFixed()四舍五入使用方法详解


Posted in Javascript onSeptember 28, 2018

最近做的项目涉及到金额的计算,有一种方式就是进行四舍五入的规则进行小数点后面的尾数处理,以前一直以为toFixed方法就是四舍五入的,知道一个用户反馈了金额计算的bug我才如梦初醒(亏了一毛钱),才仔细深究了下toFixed这个方法,唉,还是我不够严谨啊,前车之鉴,大家勿走我的老路!

toFixed还不同的浏览器实现,在IE10及以上里面是正常的四舍五入,但是别的浏览器里面就不一样了,它不是正常的四舍五入(等下重点说),比如:

var a = 1.335;
console.log(a.toFixed(2))
// IE   1.34
//chorme 1.33

其他的浏览器我没去一一测试,所以如果大家用了其他浏览器的还是需要去实际测试一下,我这里就说说javascript的toFixed()方法的四舍五入原理:

toFixed它是一个四舍六入五成双的诡异的方法(也叫银行家算法),"四舍六入五成双"含义:对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是偶数)

但是,经过我的测试发现,在chorme下面(最新版),并没有完全遵守这个规则,尤其是5的后面没有数字的时候,不是这么判断的,如下:

var b = 1.335
b.toFixed(2)
"1.33"
var b = 1.345
b.toFixed(2)
"1.34"
var b = 1.355
b.toFixed(2)
"1.35"
var b = 1.365
b.toFixed(2)
"1.36"
var b = 1.375
b.toFixed(2)
"1.38"
var b = 1.385
b.toFixed(2)
"1.39"

可以发现在chorme下没有完全去遵循这个规律,或许它有自己的算法,但是毕竟它没有遵循通用的银行家算法,所以tofixed这个方法在涉及到金钱计算的业务中还是少用,
最好别用,否则可能会出大问题!
下面再再说说我自己的做法,就是根据精确位数来取小数点后的数,然后判断精确位是大于4还是小于等于4,上代码吧,不说了:
我们的业务是最多精确到分,也就是两位小数,最少就是取整,不留小数

function moneySwitch(money, precision){//precision是需要精确的位数,如百分位就是2
 var result = 0;
 //先进行一个千分位的四舍五入,保证3.0999这种情况在保留一位小数的时候能是对的,这一位可以这么做没什么问题
 var money = parseFloat(money).toFixed(3);
 try{
  var int_part = money.split(".")[0], //小数点前的整数
  point_num = money.split(".")[1],//取小数点后面的小数
  precision_num = point_num[3-precision];
  if(precision_num>4){//五入的情况
   if(precision==1){
    point_num = parseInt(point_num)+10+"";
    if(point_num.length>3){//说明往整数位进1
     int_part = parseInt(int_part)+1+"";
     point_num = point_num[1]+point_num[2];
    }else{
     point_num = point_num[0]+point_num[1];
    }
    result = parseFloat(int_part+"."+point_num);
   }else if(precision==2){
    point_num = parseInt(point_num)+100+"";
    if(point_num.length>3){//说明往整数位进1
     int_part = parseInt(int_part)+1+"";
     point_num = point_num[1];
    }else{
     point_num = point_num[0];
    }
    result = parseFloat(int_part+"."+point_num);
   }else if(precision==3){
    int_part = parseInt(int_part)+1+"";
    point_num = 0;
   }
   result = parseFloat(int_part+"."+point_num);
  }else{//四舍的情况
   if(precision==1){
    point_num = point_num[0]+point_num[1];
   }else if(precision==2){
    point_num = point_num[0];
   }else if(precision==3){
    point_num = 0;
   }
   result = parseFloat(int_part+"."+point_num);
  } 
 }catch(e){
  return parseFloat(money).toFixed(2);//如果过程中有出错就tofixed代替为解决
 }
 return result;
}

补充:

js处理数字保留2位小数,强制保留2位小数不够补上.00

1、保留两位小数 //功能:将浮点数四舍五入,取小数点后2位

2、//制保留2位小数,如:2,会在2后面补上00.即2.00

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<script type="text/javascript" src="js/jq.js"></script>
</head>
<script type="text/javascript"> 
 //保留两位小数 
 //功能:将浮点数四舍五入,取小数点后2位 
 function toDecimal(x) { 
  var f = parseFloat(x); 
  if (isNaN(f)) { 
   return; 
  } 
  f = Math.round(x*100)/100; 
  return f; 
 } 
 
 
 //制保留2位小数,如:2,会在2后面补上00.即2.00 
 function toDecimal2(x) { 
  var f = parseFloat(x); 
  if (isNaN(f)) { 
   return false; 
  } 
  var f = Math.round(x*100)/100; 
  var s = f.toString(); 
  var rs = s.indexOf('.'); 
  if (rs < 0) { 
   rs = s.length; 
   s += '.'; 
  } 
  while (s.length <= rs + 2) { 
   s += '0'; 
  } 
  return s; 
 } 
  
 function fomatFloat(src,pos){  
   return Math.round(src*Math.pow(10, pos))/Math.pow(10, pos);  
 } 
 
 document.write("四舍五入 <br/>")
 document.write("3.14159267保留2位小数:" + toDecimal(3.14159267)+"<br/>"); 
 document.write("3.14159267强制保留2位小数:" + toDecimal2(3.14159267)+"<br/>"); 
 document.write("3.14159267保留2位小数:" + toDecimal(3.14559267)+"<br/>"); 
 document.write("3.14159267强制保留2位小数:" + toDecimal2(3.15159267)+"<br/>"); 
 document.write("3.14159267保留2位小数:" + fomatFloat(3.14559267, 2)+"<br/>"); 
 document.write("3.14159267保留1位小数:" + fomatFloat(3.15159267, 1)+"<br/>"); 
  
 document.write("五舍六入 <br/>")
 document.write("1000.003保留2位小数:" + 1000.003.toFixed(2)+"<br/>"); 
 document.write("1000.08保留1位小数:" + 1000.08.toFixed(1)+"<br/>"); 
 document.write("1000.04保留1位小数:" + 1000.04.toFixed(1)+"<br/>"); 
 document.write("1000.05保留1位小数:" + 1000.05.toFixed(1)+"<br/>"); 
  
 document.write("科学计数 <br/>")
 document.write(3.1415+"科学技术后:"+3.1415.toExponential(2)+"<br/>"); 
 document.write(3.1455+"科学技术后:"+3.1455.toExponential(2)+"<br/>"); 
 document.write(3.1445+"科学技术后:"+3.1445.toExponential(2)+"<br/>"); 
 document.write(3.1465+"科学技术后:"+3.1465.toExponential(2)+"<br/>"); 
 document.write(3.1665+"科学技术后:"+3.1665.toExponential(1)+"<br/>"); 
 document.write("精确到n位,不含n位 <br/>")
 document.write("3.1415精确到小数点第2位" + 3.1415.toPrecision(2)+"<br/>"); 
 document.write("3.1455精确到小数点第3位" + 3.1465.toPrecision(3)+"<br/>"); 
 document.write("3.1445精确到小数点第2位" + 3.1415.toPrecision(2)+"<br/>"); 
 document.write("3.1465精确到小数点第2位" + 3.1455.toPrecision(2)+"<br/>"); 
 document.write("3.166592679287精确到小数点第5位" + 3.141592679287.toPrecision(5)+"<br/>"); 
</script> 
<body>
<input type="text" id="Score" />
</body>
</html>

这篇关于toFixed()的文章就介绍到这了,希望大家以后多多支持三水点靠木。

Javascript 相关文章推荐
Javascript级联下拉菜单以及AJAX数据验证核心代码
May 10 Javascript
js获取多个tagname的节点数组
Sep 22 Javascript
jquery动态加载js/css文件方法(自写小函数)
Oct 11 Javascript
jQuery+php实时获取及响应文本框输入内容的方法
May 24 Javascript
js实现动态创建的元素绑定事件
Jul 19 Javascript
AngularJS ng-blur 指令详解及简单实例
Jul 30 Javascript
jQuery初级教程之网站品牌列表效果
Aug 02 jQuery
javascript实现Java中的Map对象功能的实例详解
Aug 21 Javascript
详解使用webpack构建多页面应用
Dec 21 Javascript
浏览器JavaScript调试功能无法使用解决方案
Sep 18 Javascript
如何用JavaScript检测当前浏览器是无头浏览器
Apr 27 Javascript
react 路由Link配置详解
Nov 11 Javascript
对vue中v-if的常见使用方法详解
Sep 28 #Javascript
总结javascript三元运算符知识点
Sep 28 #Javascript
2种在vue项目中使用百度地图的简单方法
Sep 28 #Javascript
实例分析vue循环列表动态数据的处理方法
Sep 28 #Javascript
js隐式转换的知识实例讲解
Sep 28 #Javascript
vue.js父子组件通信动态绑定的实例
Sep 28 #Javascript
解决webpack+Vue引入iView找不到字体文件的问题
Sep 28 #Javascript
You might like
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
PHP实现电商订单自动确认收货redis队列
2017/05/17 PHP
javascript移出节点removeChild()使用介绍
2014/04/03 Javascript
js实现飞入星星特效代码
2014/10/17 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
ionic 上拉菜单(ActionSheet)实例代码
2016/06/06 Javascript
Angular.js组件之input mask对input输入进行格式化详解
2017/07/10 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
2017/07/11 jQuery
Vue数组更新及过滤排序功能
2017/08/10 Javascript
详解jquery插件jquery.viewport.js学习使用方法
2017/09/08 jQuery
vue2.0 + ele的循环表单及验证字段方法
2018/09/18 Javascript
Vue列表渲染的示例代码
2018/11/01 Javascript
微信小程序实现登录注册tab切换效果
2020/12/29 Javascript
vue实现匀速轮播效果
2020/06/29 Javascript
JavaScript语句错误throw、try及catch实例解析
2020/08/18 Javascript
[03:12]2016完美“圣”典风云人物:单车专访
2016/12/02 DOTA
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
[49:12]完美世界DOTA2联赛PWL S2 Magma vs GXR 第二场 11.29
2020/12/02 DOTA
Python的类实例属性访问规则探讨
2015/01/30 Python
Python解析xml中dom元素的方法
2015/03/12 Python
Python使用openpyxl读写excel文件的方法
2017/06/30 Python
基于Python socket的端口扫描程序实例代码
2018/02/09 Python
详解Django模版中加载静态文件配置方法
2019/07/21 Python
wxpython多线程防假死与线程间传递消息实例详解
2019/12/13 Python
基于pytorch 预训练的词向量用法详解
2020/01/06 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
Python爬虫教程知识点总结
2020/10/19 Python
蛋白质世界:Protein World
2017/11/23 全球购物
编程输出如下图形
2013/11/24 面试题
laravel使用redis队列实例讲解
2021/03/23 PHP
车辆维修工自我评价怎么写
2013/09/20 职场文书
党员干部公开承诺书
2014/03/26 职场文书
镇人大副主席民主生活会对照检查材料思想汇报
2014/10/01 职场文书
县级领导干部开展党的群众路线教育实践活动工作汇报
2014/10/25 职场文书
幼儿园老师工作总结2015
2015/05/22 职场文书
新员工试用期工作总结2015
2015/05/28 职场文书