(function() { var ROOT = this; var DECIMAL_SEPARATOR = '.'; // Decimal var Decimal = function(num) { if(this.constructor != Decimal) { return new Decimal(num); } if(num instanceof Decimal) { return num; } this.internal = String(num); this.as_int = as_integer(this.internal); this.add = function(target) { var operands = [this, new Decimal(target)]; operands.sort(function(x, y) { return x.as_int.exp - y.as_int.exp }); var smallest = operands[0].as_int.exp; var biggest = operands[1].as_int.exp; var x = Number(format(operands[1].as_int.value, biggest - smallest)); var y = Number(operands[0].as_int.value); var result = String(x + y); return Decimal(format(result, smallest)); }; this.sub = function(target) { return Decimal(this.add(target * -1)); }; this.mul = function(target) { target = new Decimal(target); var result = String(Math.abs(this.as_int.value) * Math.abs(target.as_int.value)); var _symbol = this.as_int.value * target.as_int.value var exp = this.as_int.exp + target.as_int.exp; return Decimal(format(result, exp, _symbol)); }; this.div = function(target) { target = new Decimal(target); var smallest = Math.min(this.as_int.exp, target.as_int.exp); var x = Decimal.mul(Math.pow(10, Math.abs(smallest)), this); var y = Decimal.mul(Math.pow(10, Math.abs(smallest)), target); return Decimal(x / y); }; this.toString = function() { return this.internal; }; this.toNumber = function() { return Number(this.internal); } }; var as_integer = function(number) { number = String(number); var value, exp, tokens = number.split(DECIMAL_SEPARATOR), integer = tokens[0], fractional = tokens[1]; if(!fractional) { var trailing_zeros = integer.match(/0+$/); if(trailing_zeros) { var length = trailing_zeros[0].length; value = integer.substr(0, integer.length - length); exp = length; } else { value = integer; exp = 0; } } else { value = parseInt(number.split(DECIMAL_SEPARATOR).join(''), 10); exp = fractional.length * -1; } return { 'value': value, 'exp': exp }; }; // Helpers var neg_exp = function(str, position, symbol = 1) { position = Math.abs(position); const _symbol = symbol > 0 ? '' : '-' var offset = position - str.length; var sep = DECIMAL_SEPARATOR; if(offset >= 0) { str = zero(offset) + str; sep = '0.'; } var length = str.length; var head = str.substr(0, length - position); var tail = str.substring(length - position, length); return _symbol + head + sep + tail; }; var pos_exp = function(str, exp, symbol = 1) { var zeros = zero(exp); const _symbol = symbol > 0 ? '' : '-' return _symbol + String(str + zeros); }; var format = function(num, exp, symbol = 1) { num = String(num); var func = exp >= 0 ? pos_exp : neg_exp; return func(num, exp, symbol); }; var zero = function(exp) { return new Array(exp + 1).join('0'); }; // Generics var methods = ['add', 'mul', 'sub', 'div']; for(var i = 0; i < methods.length; i++) { (function(method) { Decimal[method] = function(a, b) { return new Decimal(a)[method](b); } })(methods[i]); } if(typeof module != 'undefined' && module.exports) { module.exports = Decimal; } else { ROOT.Decimal = Decimal; } })();
Decimal(.1).add(.2).toNumber() 0.3
标签:function,return,int,Decimal,js,丢失,exp,var,加减乘除 From: https://www.cnblogs.com/HePandeFeng/p/17603456.html