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 相关文章推荐
Jquery中Ajax 缓存带来的影响的解决方法
May 19 Javascript
浏览器打开层自动缓慢展开收缩实例代码
Jul 04 Javascript
JS实现双击编辑可修改状态的方法
Aug 14 Javascript
jquery采用oop模式class类的使用示例
Jan 22 Javascript
JavaScript中关联原型链属性特性
Feb 13 Javascript
常用Javascript函数与原型功能收藏(必看篇)
Oct 09 Javascript
原生js实现打字动画游戏
Feb 04 Javascript
Angular.JS中select下拉框设置value的方法
Jun 20 Javascript
在vue组件中使用axios的方法
Mar 16 Javascript
JS实现调用本地摄像头功能示例
May 18 Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
Sep 21 Javascript
Openlayers实现点闪烁扩散效果
Sep 24 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
全国FM电台频率大全 - 9 上海市
2020/03/11 无线电
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
一些被忽视的PHP函数(简单整理)
2010/04/30 PHP
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
PHP中配置IIS7实现基本身份验证的方法
2015/09/24 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
2015/12/24 PHP
PHP简单实现遍历目录下特定文件的方法小结
2017/05/22 PHP
html数组字符串拼接的最快方法
2009/09/16 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
Query中click(),bind(),live(),delegate()的区别
2013/11/19 Javascript
如何将php数组或者对象传递给javascript
2014/03/20 Javascript
javascript判断是手机还是电脑访问网页的简单实例分享
2014/06/03 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
js时钟翻牌效果实现代码分享
2020/07/31 Javascript
JQuery实现简单的服务器轮询效果实例
2016/03/31 Javascript
第一次接触神奇的Bootstrap网格系统
2016/07/27 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
vue调用高德地图实例代码
2017/04/28 Javascript
js中url对象化管理分析
2017/12/29 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
2018/01/23 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
[01:10]DOTA2 Supermajor:英雄,由我们见证
2018/05/14 DOTA
使用Python对Excel进行读写操作
2017/03/30 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
2018/05/24 Python
python3的输入方式及多组输入方法
2018/10/17 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
python中安装django模块的方法
2020/03/12 Python
Django数据结果集序列化并展示实现过程
2020/04/22 Python
印尼第一大家居、生活和家具电子商务:Ruparupa
2019/11/25 全球购物
公务员个人自我评价分享
2013/11/06 职场文书
物联网工程专业推荐信
2014/09/08 职场文书
党员个人对照检查材料
2014/10/01 职场文书
婚庆答谢词大全
2015/09/29 职场文书
java设计模式--原型模式详解
2021/07/21 Java/Android
解决redis批量删除key值的问题
2022/03/23 Redis