欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

解决JavaScript浮点数计算精度问题

程序员文章站 2022-03-30 17:10:50
...

作为一个才工作一年的萌新小程序员,第一次写博客还是有些小紧张的…2333

写博客最主要的目的也是为了记录和分享自己的心得体会…

有哪里写的不好的或者有误的地方还请各位前辈多多指教,小弟感激不尽,哈哈

--------------------------------------------------------------------------------分割线------------------------------------------------------------------------------

接下来步入正题, 话说之前在使用JS开发过程中发现计算某些浮点数的时候,出现了精度问题 ! 导致出现了一些错误 !

比如: 0.1 + 0.2 = 0.30000000000000004 计算结果并不是我们想要的结果 0.3

刚开始发现的时候我也很纳闷, 这是怎么出现的 ? 后面去百度了一下,才知道原来是由于某些浮点数不能精确的转换成二进制造成的 !

1. 那么 如何将小数转换成二进制呢?

1) 整数部分:除二取余,然后倒序排列,高位补零
2) 小数部分:小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0

例如: 0.1 转换成二进制

0.1 * 2 = 0
0.2 * 2 = 0
0.4 * 2 = 0
0.8 * 2 = 1
0.6 * 2 = 1
0.2 * 2 = 0
0.4 * 2 = 0
0.8 * 2 = 1
0.6 * 2 = 1

由于0.1 的二进制 0.000110011001100… 无限循环的

然而最终在计算机中存储的数值是有限的. 所以只能保留多少位…

2.我的解决思路:

先把小数转成整数.在计算, 最后把结果再转换成小数就ok了.


function MathTool() {

	//获取小数长度
	var getDecimalsLength = function (num) {
		return num.toString().split(".")[1] ? num.toString().split(".")[1].length : 0
	}
	
	//获取最大长度
	
	var getMaxLength = function (num1, num2) {
	
		var num1Length = getDecimalsLength(num1);
		
		var num2Length = getDecimalsLength(num2);
		
		var p = Math.max(num1Length, num2Length);
		
		var times = Math.pow(10, p);
		
		return times
	
	}
	
	//加法
	
	this.add = function(num1, num2) {
	
		var times = getMaxLength(num1, num2);
		
		return (this.mul(num1 ,times) + this.mul(num2 ,times)) / times;
		
	}
	
	//减法
	
	this.sub = function(num1, num2) {
	
		var times = getMaxLength(num1, num2);
		
		return (this.mul(num1 ,times) - this.mul(num2 , times)) / times;
		
	}
	
	//乘法
	
	this.mul = function(num1, num2) {
	
		var times = getMaxLength(num1, num2);
		
		var intNum1 = num1.toString().replace(".", "")
		
		var intNum2 = num2.toString().replace(".", "")
		
		var countDecimals = getDecimalsLength(num1) + getDecimalsLength(num2)
		
		return intNum1 * intNum2 / Math.pow(10, countDecimals);
		
	}
	
	//除法
	
	this.div = function(num1, num2) {
	
		var times = getMaxLength(num1, num2);
		
		return (this.mul(num1 , times) / this.mul(num2 , times));
		
	}
	
}
	
	var MathTool = new MathTool();
	console.log(MathTool.add(0.1, 0.2))
	console.log(MathTool.sub(0.0012, 0.0002))