`
greemranqq
  • 浏览: 966419 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

JS 计算 精度 问题

阅读更多

     我们经常会在页面进行数据的计算,当用javascript 进行计算的时候,有可能会出现 精度 问题!

      记录下来,让我们新手参考!

 

     我们先来分析下原因,查阅了相关资料:

      1. javascript  数字是以IEEE_754 (http://zh.wikipedia.org/zh-cn/IEEE_754)格式表示。

      2.计算的执行,我们知道都是以二进制进行操作的。

      3.至于IEEE 的详细内容在这里我就不详细解释了,简单的说就是浮点类型的数字,二进制数不能完全正确表示。

      4.同理,当我们浮点类型数字进行运算的时候,也就不能完全正确表示了。

 

      那应该如何操作呢?

      1. javascript 不是提供了Number 和 parseFloat 吗?难道不可以用吗?看看以下代码。

 

 

var a = 9.2;
var b = 4.2;
var result = Number(a)+Number(b);
alert(result);

      预期结果:13.4     实际结果:13.99999..

      如果这样呢?

 

var a = 9.2;
var b = 4.2;
var result = Number(a)+Number(b);
alert(result.toFixed(2));

      预期结果:13.40     实际结果:13.40

      好像可以了!那么这样呢?

 

var a = 0.007;
var b = 0.002;
var result = Number(a)+Number(b);
alert(result.toFixed(2));

      预计结果是:0.01

      IE    实际结果:0.00

      Chrome 实际结果:0.01  

     火狐 实际结果:0.01

      看来和浏览器内部解析和设置有关!那我们尝试下面的方法。

 

     2.扩大倍数

 

// 乘以需要保留位数加1,比如需要保留n(n=2)位 + 1,就乘1000
// 或者乘以 m,可以将所有的小数变为整数 
var a = 9.2;
var b = 4.2;
var result = Number(a*1000)+Number(b*1000);
result  = result/1000)
alert(result.toFixed(2));

      预期结果:13.40     实际结果:13.40

      好像也是可以的,但是...

 

  
var a = 0;
var b = 512.06;
var result = Number(a*100)+Number(b*100);
alert(result);
alert(result/100);
alert((result/100).toFixed(2));
 

     分别输出:51205.9999......  ,   512.06   , 512.06

     虽然计算  result 是有偏差的,但是经过还原 最终是能拿到结果的。浮点类型参与乘法运行也会失精的,看着可以,其实其实我们找到合适的数据来推翻。在这里假设:乘以一个很大的数:10000....,最后再除以,是否能得到我们满意的答案呢?也请大家给点建议,以及数据进行测试。

 

      3.字符串处理方式,思想和上面差不多

 

// num1,num2 参数,index 保留的位数
function dealNum(num1,num2,index){
	var result = 0;
	// 获得两个小数长度
	var numa = num1.toString();
	var numb = num2.toString();
	// 分别记录两数小数长度
	var lena = 0;
	var lenb = 0;
	// 最长小数的长度
	var lastLen = 0 ;
	if(numa.indexOf('.') > 0){
		lena = numa.split('.')[1].length;
	}
	if(numb.indexOf('.') > 0){
		lenb = numb.split('.')[1].length;
	}
	// 去掉小数点
	numa = numa.replace('.','');
	numb = numb.replace('.','');
	if(lena > lenb ){
		lastLen  = lena;
	}else{
		lastLen  = lenb;
	}
	// 做相应的加减乘除(这里只做加法运算,其他差不多)
	result =  Number(numa)+Number(numb);
	result = result/Math.pow(10,lastLen);
	return result.toFixed(index);
}
 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics