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

最近做的项目涉及到金额的计算,有一种方式就是进行四舍五入的规则进行小数点后面的尾数处理,以前一直以为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()的文章就介绍到这了,希望大家以后多多支持我们。

(0)

相关推荐

  • JS处理数据四舍五入(tofixed与round的区别详解)

    1 .tofixed方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法.具体规则如下: 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一. 显然这种规则不符合我们平常在数据中处理的方式.为了解决这样的问题,可以自定义

  • js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)

    js中小数向上取整数,向下取整数,四舍五入取整数的实现. 1.ceil()  向上-------------ceil英文意思是:天花板-----------就是在上 2.floor() 向下-------------ceil英文意思是:地面-----------就是在下 3.round() 四舍五入-------------ceil英文意思是:大约-----------就是附近 直接看下面的例子,结果一目了然.代码下面的是对应的打印结果. Math.floor(3/4) 0 Math.floor

  • JS用最简单的方法实现四舍五入

    1 .tofixed方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法.具体规则如下: 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一. 显然这种规则不符合我们平常在数据中处理的方式.为了解决这样的问题,可以自定义

  • JS实现保留n位小数的四舍五入问题示例

    本文实例讲述了JS实现保留n位小数的四舍五入问题.分享给大家供大家参考,具体如下: //数字四舍五入(保留n位小数) getFloat = function (number, n) { n = n ? parseInt(n) : 0; if (n <= 0) return Math.round(number); number = Math.round(number * Math.pow(10, n)) / Math.pow(10, n); return number; }; /* //用法示例:

  • JS使用tofixed与round处理数据四舍五入的区别

    1 .tofixed方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法.具体规则如下: 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一. 显然这种规则不符合我们平常在数据中处理的方式.为了解决这样的问题,可以自定义

  • js实现四舍五入完全保留两位小数的方法

    本文实例讲述了js实现四舍五入完全保留两位小数的方法.分享给大家供大家参考,具体如下: //四舍五入保留2位小数(若第二位小数为0,则保留一位小数) function keepTwoDecimal(num) { var result = parseFloat(num); if (isNaN(result)) { alert('传递参数错误,请检查!'); return false; } result = Math.round(num * 100) / 100; return result; }

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

    最近做的项目涉及到金额的计算,有一种方式就是进行四舍五入的规则进行小数点后面的尾数处理,以前一直以为toFixed方法就是四舍五入的,知道一个用户反馈了金额计算的bug我才如梦初醒(亏了一毛钱),才仔细深究了下toFixed这个方法,唉,还是我不够严谨啊,前车之鉴,大家勿走我的老路! toFixed还不同的浏览器实现,在IE10及以上里面是正常的四舍五入,但是别的浏览器里面就不一样了,它不是正常的四舍五入(等下重点说),比如: var a = 1.335; console.log(a.toFix

  • javascript中的数据类型检测方法详解

    本文实例讲述了javascript中的数据类型检测方法.分享给大家供大家参考,具体如下: 在javascript中数据类型 值类型: 布尔(Boolean),数值(Number),字符(String),空(Null),未定义(Undefined) 引用类型: 对象(Object),函数(Function),数组(Array),日期(Date),正则(RegExp)等等. 检测方式之 typeof console.log(typeof undefined)//'undefined' console

  • JavaScript中this关键字使用方法详解

    在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了,用起来是非常方便和意义确定的.JavaScript也提供了这个this关键字,不过用起来就比经典OO语言中要"混乱"的多了. 下面就来看看,在JavaScript中各种this的使用方法有什么混乱之处? 1.在HTML元素事件属性中inline方式使用this关键字: <div onclick="  // 可以在里面使用

  • JavaScript中arguments的使用方法详解

    前言 js这是一门弱语言,不像其他语言如c,java等,有严格的规范, 所以现在也流传着一种说法,js本来就不是一种语言: 说回arguments,它是js中函数内置的一个对象,而执行函数方法的实参中值都存储在arguments中: 要想获取到这些实参,就需要像数组一样,用下标/索引来定位到每个值上面,但是又不能说它是一个数组,因为它里面还有其他的属性,如callee; 并且不能对它使用shift.push.join等方法.而没有传递值的命名参数将会被自动赋予undefined: 如下图: (如

  • javascript中定义类的方法详解

    JS中定义类的方式有很多种: 1.工厂方式 复制代码 代码如下: function Car(){    var ocar = new Object;    ocar.color = "blue";    ocar.doors = 4;    ocar.showColor = function(){     document.write(this.color)    };    return ocar;   }   var car1 = Car();   var car2 = Car()

  • JavaScript中Object值合并方法详解

    前言:在日常开发工作中我们可能会遇到js中对象中所有值的复制工作,也有可能是通过electron开发客户端,改版时候面临到的设置合并问题.那么本文将对此做一个简要解决方案的叙述. 介绍:比如有obj1, obj2,我们需要将obj1中的所有与obj2中相同字段相同深度的值copy给obj2,并且需要保持obj2字段结构不变,调用一下方法即可(采用ES6写法). 代码: /** * 将src中的数据copy到dist中,并保留dist的结构 * @param src * @param dist *

  • JavaScript中splice的使用方法详解

    splice方法可以用来对js的数组进行删除,添加,替换等操作. 1. 删除功能,第一个参数为第一项位置,第二个参数为要删除几个. 用法:array.splice(index,num),返回值为删除内容,array为结果值. 2. 插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项). 用法:array.splice(index,0,insertValue),返回值为空数组,array值为最终结果值. 3. 替换功能,第一个参数(起始位置),第二个参数(删除的项数),第三个

  • JavaScript中push(),join() 函数 实例详解

    定义和用法 push方法 可向数组的末尾添加一个或多个元素,并返回一个新的长度. join方法 用于把数组中所有元素添加到一个指定的字符串,元素是通过指定的分隔符进行分割的. 语法 arrayObject.push(newelement1,newelement2,....,newelementX) arrayObject.join(separator). 参数描述newelement1必需.要添加到数组的第一个元素.newelement2可选.要添加到数组的第二个元素.newelementX可选

  • JavaScript中浅讲ajax图文详解

    1.ajax入门案例 1.1 搭建Web环境 ajax对于各位来说,应该都不陌生,正因为ajax的产生,导致前台页面和服务器之间的数据传输变得非常容易,同时还可以实现页面的局部刷新.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 对于JavaWeb项目而言,ajax主要用于浏览器和服务器之间数据的传输. 如果是单单地堆砌知识点,会显得比较无聊,那么根据惯例,我先不继续介绍ajax,而是来写一个案例吧. 打开

  • jQueryUI中的datepicker使用方法详解

    jQuery UI很强大,其中的日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加相关按钮以及其它导航等. 之前做的一个排班考勤系统,跟时间打交道较多,对时间控件做过一些对比,觉得jqueryUI里的这个datepicker更为实用,下面抽点时间给大家整理,方便以后查阅,同时也希望能帮助到大家! 1,引入js,css <link rel="stylesheet" href="http://code.

随机推荐