acdr-ui/dist/dev/mp-weixin/sheep/helper/digit.js.map

1 line
5.9 KiB
Plaintext
Raw Normal View History

2024-09-19 07:20:14 +08:00
{"version":3,"file":"digit.js","sources":["../../../../../src/sheep/helper/digit.js"],"sourcesContent":["let _boundaryCheckingState = true // 是否进行越界检查的全局开关\r\n\r\n/**\r\n * 把错误的数据转正\r\n * @private\r\n * @example strip(0.09999999999999998)=0.1\r\n */\r\nfunction strip(num, precision = 15) {\r\n return +parseFloat(Number(num).toPrecision(precision))\r\n}\r\n\r\n/**\r\n * Return digits length of a number\r\n * @private\r\n * @param {*number} num Input number\r\n */\r\nfunction digitLength(num) {\r\n // Get digit length of e\r\n const eSplit = num.toString().split(/[eE]/)\r\n const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0)\r\n return len > 0 ? len : 0\r\n}\r\n\r\n/**\r\n * 把小数转成整数,如果是小数则放大成整数\r\n * @private\r\n * @param {*number} num 输入数\r\n */\r\nfunction float2Fixed(num) {\r\n if (num.toString().indexOf('e') === -1) {\r\n return Number(num.toString().replace('.', ''))\r\n }\r\n const dLen = digitLength(num)\r\n return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num)\r\n}\r\n\r\n/**\r\n * 检测数字是否越界,如果越界给出提示\r\n * @private\r\n * @param {*number} num 输入数\r\n */\r\nfunction checkBoundary(num) {\r\n if (_boundaryCheckingState) {\r\n if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {\r\n console.warn(`${num} 超出了精度限制,结果可能不正确`)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 把递归操作扁平迭代化\r\n * @param {number[]} arr 要操作的数字数组\r\n * @param {function} operation 迭代操作\r\n * @private\r\n */\r\nfunction iteratorOperation(arr, operation) {\r\n const [num1, num2, ...others] = arr\r\n let res = operation(num1, num2)\r\n\r\n others.forEach((num) => {\r\n res = operation(res, num)\r\n })\r\n\r\n return res\r\n}\r\n\r\n/**\r\n * 高精度乘法\r\n * @export\r\n */\r\nexport function times(...nums) {\r\n if (nums.length > 2) {\r\n return iteratorOperation(nums, times)\r\n }\r\n\r\n const [num1, num2] = nums\r\n const num1Changed = float2Fixed(num1)\r\n const num2Changed = float2Fixed(num2)\r\n const baseNum = digitLength(num1) + digitLength(num2)\r\n const leftValue = num1Changed * num2Changed\r\n\r\n checkBoundary(leftValue)\r\n\r\n return leftValue / Math.pow(10, baseNum)\r\n}\r\n\r\n/**\r\n * 高精度加法\r\n * @export\r\n */\r\nexport function plus(...nums) {\r\n if (nums.length > 2) {\r\n return iteratorOperation(nums, plus)\r\n }\r\n\r\n const [num1, num2] = nums\r\n // 取最大的小数位\r\n const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)))\r\n // 把小数都转为整数然后再计算\r\n return (times(num1, baseNum) + times(num2, baseNum)) / baseNum\r\n}\r\n\r\n/**\r\n * 高精度减法\r\n * @export\r\n */\r\nexport function minus(...nums) {\r\n if (nums.length > 2) {\r\n return iteratorOperation(nums, minus)\r\n }\r\n\r\n const [num1, num2] = nums\r\n const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)))\r\n return (times(num1, baseNum) - times(num2, baseNum)) / baseNum\r\n}\r\n\r\n/**\r\n * 高精度除法\r\n * @export\r\n */\r\nexport function divide(...nums) {\r\n if (nums.length > 2) {\r\n return iteratorOperation(nums, divide)\r\n }\r\n\r\n const [num1, num2] = nums\r\n const num1Changed = float2Fixed(num1)\r\n const num2Changed = float2Fixed(num2)\r\n checkBoundary(num1Changed)\r\n checkBoundary(num2Changed)\r\n // 重要这里必须用strip进行修正\r\n return times(\r\n num1Changed / num2Changed,\r\n strip(Math.pow(10, digitLength(num2) - digitLength(num1))),\r\n )\r\n}\r\n\r\n/**\r\n * 四舍五入\r\n * @export\r\n */\r\nexport function round(num, ratio) {\r\n const base = Math.pow(10, ratio)\r\n let result = divide(Math.round(Math.abs(times(num, base))), base)\r\n if (num < 0 && result !== 0) {\r\n result = times(result, -1)\r\n }\r\n // 位数不足则补0\r\n return result\r\n}\r\n\r\n/**\r\n * 是否进行边界检查,默认开启