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 相关文章推荐
MooTools 页面滚动浮动层智能定位实现代码
Aug 23 Javascript
js Array对象的扩展函数代码
Apr 24 Javascript
javascript arguments使用示例
Dec 16 Javascript
js实现可折叠展开的手风琴菜单效果
Sep 07 Javascript
实例详解jQuery的无new构建
Aug 02 Javascript
JS实战篇之收缩菜单表单布局
Dec 10 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
Jan 03 Javascript
Jqprint实现页面打印
Jan 06 Javascript
D3.js中强制异步文件读取同步的几种方法
Feb 06 Javascript
jQuery实现验证码功能
Mar 17 Javascript
使用 jQuery 实现表单验证功能
Jul 05 jQuery
vue router+vuex实现首页登录验证判断逻辑
May 17 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中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
PHP fopen中文文件名乱码问题解决方案
2020/10/28 PHP
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
jQuery toggleClass应用实例(附效果图)
2014/04/06 Javascript
js控制容器隐藏出现防止样式变化的两种方法
2014/04/25 Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
2014/10/10 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
JavaScript解析JSON格式数据的方法示例
2017/01/24 Javascript
AngularJs表单校验功能实例代码
2017/02/09 Javascript
详解用vue编写弹出框组件
2017/07/04 Javascript
基于iScroll实现内容滚动效果
2018/03/21 Javascript
jQuery实现的网站banner图片无缝轮播效果完整实例
2019/01/28 jQuery
JS+php后台实现文件上传功能详解
2019/03/02 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
8个非常实用的Vue自定义指令
2020/12/15 Vue.js
Vue.extend 登录注册模态框的实现
2020/12/29 Vue.js
Python登录并获取CSDN博客所有文章列表代码实例
2017/12/28 Python
Tensorflow卷积神经网络实例
2018/05/24 Python
python自动发送邮件脚本
2018/06/20 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
python实现归并排序算法
2018/11/22 Python
Pycharm新建模板默认添加个人信息的实例
2019/07/15 Python
Python Django 实现简单注册功能过程详解
2019/07/29 Python
python实现用类读取文件数据并计算矩形面积
2020/01/18 Python
详解字符串在Python内部是如何省内存的
2020/02/03 Python
基于TensorFlow中自定义梯度的2种方式
2020/02/04 Python
五款漂亮的纯CSS3动画按钮的实例教程
2014/11/21 HTML / CSS
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2015/09/07 面试题
大型车展策划方案
2014/02/01 职场文书
公务员更新知识培训实施方案
2014/03/31 职场文书
文明礼貌演讲稿
2014/05/12 职场文书
机器人瓦力观后感
2015/06/12 职场文书
给学校的建议书400字
2015/09/14 职场文书
2016年基层党支部书记公开承诺书
2016/03/25 职场文书