UNPKG

calculate-asmd

Version:

The precise addition, subtraction, multiplication and division of JavaScript avoids the error of floating point calculation

237 lines (197 loc) 5.93 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /** * [scaleNum 将一个number浮点数放大或缩小position个小数点位数] * @param {number} number 要放缩的浮点数 * @param {number} position 小数点移动位数 * position大于0为放大,小于0为缩小,等于0不做缩放。 * @return {number} 放缩后的数 */ var scaleNum = function scaleNum() { var number = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var num = Number(number); var posNum = Number(position); // 如果传入两个参数,Number转化后为NaN则直接返回NaN if (isNaN(num) || isNaN(posNum)) { return NaN; } if (num === 0 || posNum === 0) { return num; } var absNum = num; var s = 1; if (num < 0) { absNum = Math.abs(num); s = -1; } var parts = absNum.toString().split('.'); var intLen = parts[0].length; var decimalLen = parts[1] ? parts[1].length : 0; if (posNum > 0) { // 放大 var zeros = posNum - decimalLen; while (zeros > 0) { zeros -= 1; parts.push(0); } } else { // 缩小 var _zeros = Math.abs(posNum) - intLen; while (_zeros > 0) { _zeros -= 1; parts.unshift(0); } } var idx = intLen + posNum; parts = parts.join('').split(''); parts.splice(idx > 0 ? idx : 0, 0, '.'); if (s < 0) { parts.unshift('-'); } return parseFloat(parts.join('')); }; /** * [add 通过比较两个加数谁的小数位最大,将两数小数点右移为整数进行计算] * @param {number} arg1 加数 * @param {number} arg2 被加数 * @return {number} 结果 */ var add = function add() { var arg1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var arg2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var param1 = Number(arg1); var param2 = Number(arg2); if (isNaN(param1) || isNaN(param2)) { return NaN; } var r1 = 0; var r2 = 0; var scale = 0; try { r1 = param1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = param2.toString().split('.')[1].length; } catch (e) { r2 = 0; } scale = Math.max(r1, r2); var num1 = scaleNum(param1, scale); var num2 = scaleNum(param2, scale); var num = num1 + num2; var result = scaleNum(num, -scale); return result; }; /** * [sub 通过比较两个加数谁的小数位最大,将两数小数点右移为整数进行计算] * @param {number} arg1 减数 * @param {number} arg2 被减数 * @return {number} 结果 */ var sub = function sub() { var arg1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var arg2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var param1 = Number(arg1); var param2 = Number(arg2); if (isNaN(param1) || isNaN(param2)) { return NaN; } var r1 = 0; var r2 = 0; var scale = 0; try { r1 = param1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = param2.toString().split('.')[1].length; } catch (e) { r2 = 0; } scale = Math.max(r1, r2); var num1 = scaleNum(param1, scale); var num2 = scaleNum(param2, scale); var num = num1 - num2; var result = scaleNum(num, -scale); return result; }; /** * [mul 将两个浮点数参数replace掉小数点为整数计算,scale在这里进行累计小数位] * @param {number} arg1 乘数 * @param {number} arg2 被乘数 * @return {number} 结果 */ var mul = function mul() { var arg1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var arg2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var param1 = Number(arg1); var param2 = Number(arg2); if (isNaN(param1) || isNaN(param2)) { return NaN; } var num1 = Number(param1.toString().replace('.', '')); var num2 = Number(param2.toString().replace('.', '')); var scale = 0; try { scale += param1.toString().split('.')[1].length; } catch (e) { scale += 0; } try { scale += param2.toString().split('.')[1].length; } catch (e) { scale += 0; } var num = num1 * num2; var result = scaleNum(num, -scale); return result; }; /** * [div 将两个浮点数参数replace掉小数点为整数计算,scale是被除数与除数的移动位数差] * @param {number} arg1 除数 * @param {number} arg2 被除数 * @return {number} 结果 */ var div = function div() { var arg1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var arg2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var param1 = Number(arg1); var param2 = Number(arg2); if (isNaN(param1) || isNaN(param2)) { return NaN; } var num1 = Number(param1.toString().replace('.', '')); var num2 = Number(param2.toString().replace('.', '')); var left1 = 0; var left2 = 0; try { left1 = Number(param1.toString().split('.')[1].length); } catch (e) { left1 = 0; } try { left2 = Number(param2.toString().split('.')[1].length); } catch (e) { left2 = 0; } /** * 当被除数100是整数没有移动小数位,那么left2为0,除数0.57在运算中转整数为57。 * 在实际的运算中0.57除以100中的0.57是根据被除数来移动小数的。 * 所以,0 - 2 = -2。 将运算结果缩小两位为实际小数点位置 * * 除数多拿了被除数的几口口粮,最后要还回去的。 * */ var scale = left2 - left1; var num = num1 / num2; var result = scaleNum(num, scale); return result; }; exports.add = add; exports.div = div; exports.mul = mul; exports.scaleNum = scaleNum; exports.sub = sub;