/** * 数学计算工具类 * @author 冯聪 */ export default class MathUtil { /** 计算两点之间距离 */ dis(x1, y1, x2, y2): number { return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); } /** * 取一个区间内随机整数 * @param n 开始位置 * @param m 结束位置 * @param ifInt 是否是整数 * @returns 返回的随机整数 */ public random(n: number, m: number, ifInt: boolean = true): number { let random: number = n; if (ifInt) { random = Math.floor(Math.random() * (m - n + 1) + n); } else { random = Math.random() * (m - n) + n; } return random; } /** * 根据权重随机 * @param weights 权重数组 * @param total 权重总值 默认100 * @param asc 权重为降序排列 * @returns */ public randomByWeight(weights: number[], total = 100, asc: boolean = true): number { if (total != 100) { total = 0; for (let i = 0; i < weights.length; i++) { total += weights[i]; } } let random = Math.random() * total; let arr = weights.concat(random); arr = arr.sort((a, b) => { return asc ? a - b : b - a; }); var randomIndex = arr.indexOf(random); randomIndex = Math.min(randomIndex, weights.length - 1); return randomIndex; } //---------------------------------------------------------科学计数法----------------------------------------------------- /**数字单位 */ private numUnit = { 4: "万", 8: "亿", 12: "兆", 16: "万兆", 20: "亿兆", 24: "兆兆", 28: "万兆兆", 32: "亿兆兆", 36: "兆兆兆" }; /** * 超大数值加法运算 忽略小数部分 * @param a * @param b */ public addition(a: string, b: string): string { var res: any = '', temp: any = 0; let a1 = a.split('.')[0].split(''); let b1 = b.split('.')[0].split(''); while (a1.length || b1.length || temp) { temp += ~~a1.pop() + ~~b1.pop(); res = (temp % 10) + res; temp = temp > 9; } return res.replace(/^0+/, ''); } /** * 超大数值减法运算 忽略小数部分 * @param a * @param b */ public subtraction(a: any, b: any): string { a = a.split('.')[0].split(''); b = b.split('.')[0].split(''); var aMaxb = a.length > b.length; if (a.length == b.length) { for (var i = 0, len = a.length; i < len; i++) { if (a[i] == b[i]) continue; aMaxb = a[i] > b[i]; break; } } if (!aMaxb) a = [b, b = a][0]; var result = ''; while (a.length) { var temp = parseInt(a.pop()) - parseInt(b.pop() || 0); if (temp >= 0) result = temp + result; else { result = temp + 10 + result; a[a.length - 1]--; } } result = (aMaxb ? '' : '-') + result.replace(/^0*/g, ''); if (result == '-') { result = '0' } return result } /** * 超大数值高位对比 忽略小数部分 * @param a * @param b */ public contrastNumber(a: any, b: any): boolean { a = a.split('.')[0].split(''); b = b.split('.')[0].split(''); var aMaxb = a.length > b.length; if (a.length == b.length) { for (var i = 0, len = a.length; i < len; i++) { if (a[i] == b[i]) continue; aMaxb = a[i] > b[i]; break; } } if (!aMaxb) a = [b, b = a][0]; var result = ''; while (a.length) { var temp = parseInt(a.pop()) - parseInt(b.pop() || 0); if (temp >= 0) result = temp + result; else { result = temp + 10 + result; a[a.length - 1]--; } } if (a === b) return true; return Boolean(aMaxb); } /** * 数值乘法 * @param a * @param b */ public accMuls(a, b): string { let arra = a.split('').reverse(), arrb = b.split('').reverse(), lena = arra.length, lenb = arrb.length, result: any = Array(lena + lenb + 1).join('0').split(''); arra.map((itema, indexa) => { arrb.map((itemb, indexb) => { result[indexa + indexb] = +result[indexa + indexb] + itema * itemb; }); }); result.map((item, index) => { if (item >= 10) { result[index + 1] = ~~result[index + 1] + ~~(result[index] / 10); result[index] %= 10; } }); return result.reverse().join('').replace(/^0+/, ''); } /** * 超大数值乘法 * @param arg1 * @param arg2 */ public accMul(arg1: string, arg2: string): string { var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); try { m += s1.split(".")[1].length } catch (e) { } try { m += s2.split(".")[1].length } catch (e) { } let targe = this.accMuls(s1.replace(".", ""), s2.replace(".", "")); return this.accDiv(targe, Math.pow(10, m).toString()) } /** 科学技术法转为数值字符串形式 */ public toNonExponential(num: number): string { return num.toLocaleString().replace(/[,]/g, '') } /** * 超大数值除法运算 * @param arg1 * @param arg2 */ public accDiv(arg1: string, arg2: string): string { var t1 = 0, t2 = 0, t3 = 0, r1, r2; try { t1 = arg1.toString().split(".")[1].length } catch (e) { } try { t2 = arg2.toString().split(".")[1].length } catch (e) { } r1 = Number(arg1.toString().replace(".", "")) r2 = Number(arg2.toString().replace(".", "")) if (r2 == 0) return '0'; var result = String(r1 / r2); try { t3 = result.toString().split(".")[1].length } catch (e) { } var index = t2 - t1 - t3; if (index < 0) { result = result.replace(".", ""); while (result.length <= Math.abs(index)) { result = '0' + result; } var start = result.substring(0, result.length + index); var end = result.substring(result.length + index, result.length); result = start + '.' + end; return this.toNonExponential(Number(result)); } else if (index > 0) { result = result.replace(".", ""); while (result.length <= Math.abs(index)) { result += '0'; } return this.toNonExponential(Number(result)); } else return this.toNonExponential(Number(result.replace(".", ""))); } /** * 数值格式化 * @param value * @param showDeci */ public format(value: string, showDeci: boolean = true): string { var a = value.split('.')[0]; var b; for (let i in this.numUnit) { let ii = Number(i); if (a.length - 1 >= ii) { if (showDeci) { let deci = a.slice(a.length - ii, a.length - ii + 1) if (Number(deci) >= 1) { b = a.slice(0, a.length - ii) + "." + deci + this.numUnit[ii]; } else { b = a.slice(0, a.length - ii) + this.numUnit[ii]; } } else { b = a.slice(0, a.length - ii) + this.numUnit[ii]; } } }; if (!b) return a; return b; } }