javascript中关于浮点数不精确问题解决方案

不支持负数和数过大的情况,但是实用在前端中一些实战情况,比如价格等。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>精确度</title>
</head>
<body>
<script>

var FloatOper = (function(){
	// 表达式处理函数
	var FloatOper = function(s){
		return _CreateFO(s).result;
	};
	//将表达式字符串转化成一个对象
	function _CreateFO(s){
		var item = s.match(/^\s*([^\+\-\*\/]+)\s*([\+\-\*\/])\s*([^\+\-\*\/]+)\s*$/);
		return new FO(item[1],item[2],item[3]);
	}
	// 表达式对象
	function FO(val1,oper,val2){
		this.val1 = this.F2I(parseFloat(val1));
		this.oper = oper;
		this.val2 = this.F2I(parseFloat(val2));
		this.resultObj = this.getResult();
		this.result =this.I2F(this.resultObj);
	}
	FO.prototype.getResult = function(){
		return this[this.oper]();
	};
	/*传入一个浮点数
	返回一个对象{value:整数表示,bit:小数位}
	*/
	FO.prototype.F2I = function(value){
		value = value+"";
		var spt = value.search(/\./),bit;
		if(spt ==-1){
			bit = 0;
		}else{
		 bit = value.length-1 - spt;
		}
		var Fnum = parseInt(value.replace(/\./,""),10);
		return {value:Fnum,bit:bit};

	};
	/*
	传入一个对象{value:val,bit:b}
	返回一个浮点数
	*/
	FO.prototype.I2F = function(valBit){
		var zf = (valBit.value>=0)?(1):(-1);
		var numStr = zf*valBit.value+"";
		var numLen = numStr.length;
		var arrNum = [];
		if(numLen <= valBit.bit){
			for(var i = 0; i<valBit.bit-numLen+1; i++){
				arrNum.push("0");
			}
		}
		arrNum = arrNum.concat(numStr.split(""));
		arrNum.splice((arrNum.length-valBit.bit),0,".");
		return zf*parseFloat(arrNum.join(""));
	};
	FO.prototype["+"] = function(){
		var c = this.val1.bit-this.val2.bit;
		var minVal = (c > 0)?this.val2:this.val1;
		var maxVal = (c < 0)?this.val2:this.val1;
		return {
			value:minVal.value*Math.pow(10,Math.abs(c))+maxVal.value,
			bit: maxVal.bit
		};

	};

	FO.prototype["-"] = function(){
		var c = this.val1.bit-this.val2.bit;
		if(this.val1.bit > this.val2.bit){
			return {
				value:this.val1.value - this.val2.value*(Math.pow(10,Math.abs(c))),
				bit:this.val1.bit
			}
		}else{
			return {
				value:this.val1.value*(Math.pow(10,Math.abs(c))) - this.val2.value,
				bit:this.val2.bit
			}
		}
	};

	FO.prototype["*"] = function(){
		return {
			value:this.val1.value*this.val2.value,
			bit:this.val1.bit+this.val2.bit
		}
	};

	FO.prototype["/"] = function(){
		var c = this.val1.bit-this.val2.bit;
		if(this.val1.bit > this.val2.bit){
			return {
				value:this.val1.value / (this.val2.value*(Math.pow(10,Math.abs(c)))),
				bit:0
			}
		}else{
			return {
				value:(this.val1.value*(Math.pow(10,Math.abs(c))) )/ this.val2.value,
				bit:0
			}
		}
	};

	return FloatOper;
})(window);
console.log(FloatOper("0.3 - 0.2"));//0.1
console.log(0.3-0.2);//0.09999999999999998
console.log(FloatOper("19.99 * 100"));//1999
console.log(19.99*100);//1998.9999999999998
console.log(FloatOper("19.99 / 100"));//0.1999

</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值