zoukankan      html  css  js  c++  java
  • toFixed方法的bug

    最近在工作过程中碰到一个隐藏的bug,经调试发现竟然是toFixed函数不可靠的结果引起的。后端同学在处理价格比较的时候,用foFixed进行价格的四舍五入之后,竟然发现比较的结果有问题;

    大家都知道,Number类型的变量有个toFixed方法,该方法将Number四舍五入为指定小数位数的数字,以字符串返回。

    IE:

    0.6 .toFixed(0); // 0
    1.6 .toFixed(0); // 2

    Chrome:

    0.6 .toFixed(0); // 1
    1.6 .toFixed(0); // 2

    另外还发现,就算是同在Chrome里,四舍五入也不靠谱:

    ( 0.035 ).toFixed( 2 ); // 0.04
    ( 0.045 ).toFixed( 2 ); // 0.04

    这次IE倒是靠谱了:

    ( 0.035 ).toFixed( 2 ); // 0.04
    ( 0.045 ).toFixed( 2 ); // 0.05
    

    结论 :toFixed()函数靠不住,如果有需要精确控制的情况,还是自己写个方法比较好。比如:

    function toFixed(number, decimal) {
    	decimal = decimal || 0;
    	var s = String(number);
    	var decimalIndex = s.indexOf('.');
    	if (decimalIndex < 0) {
    		var fraction = '';
    		for (var i = 0; i < decimal; i++) {
    			fraction += '0';
    		}
    		return s + '.' + fraction;
    	}
    	var numDigits = s.length - 1 - decimalIndex;
    	if (numDigits <= decimal) {
    		var fraction = '';
    		for (var i = 0; i < decimal - numDigits; i++) {
    			fraction += '0';
    		}
    		return s + fraction;
    	}
    	var digits = s.split('');
    	var pos = decimalIndex + decimal;
    	var roundDigit = digits[pos + 1];
    	if (roundDigit > 4) {
    		//跳过小数点
    		if (pos == decimalIndex) {
    			--pos;
    		}
    		digits[pos] = Number(digits[pos] || 0) + 1;
    		//循环进位
    		while (digits[pos] == 10) {
    			digits[pos] = 0;
    			--pos;
    			if (pos == decimalIndex) {
    				--pos;
    			}
    			digits[pos] = Number(digits[pos] || 0) + 1;
    		}
    	}
    	//避免包含末尾的.符号
    	if (decimal == 0) {
    		decimal--;
    	}
    	return digits.slice(0, decimalIndex + decimal + 1).join('');
    }
    var a = 19.02
    var b = 209.01
    // 结果
    console.log(toFixed(a, 2)); //==> 19.02
    console.log(toFixed(b, 2)); //==> 209.01
    console.log(Number(toFixed(a, 2)) < Number(toFixed(b, 2))); //==> true
  • 相关阅读:
    【Linux】【Services】【SaaS】Docker+kubernetes(2. 配置NTP服务chrony)
    【Linux】【Services】【DNS】使用Bind搭建DNS服务
    【Linux】【Services】【SaaS】Docker+kubernetes(1. 基础概念与架构图)
    【Services】【Web】【LVS】lvs基础概念
    jquery.cookie.js 配置
    SQL Server2008 TIME类型
    Ext.MessageBox
    Ext.Form 自动填写表单内容
    Ext 中xtype一览
    ExtGrid
  • 原文地址:https://www.cnblogs.com/jone-chen/p/5957318.html
Copyright © 2011-2022 走看看