MathUtil.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /**
  2. * 数学计算工具类
  3. * @author 冯聪
  4. */
  5. export default class MathUtil {
  6. /** 计算两点之间距离 */
  7. dis(x1, y1, x2, y2): number {
  8. return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
  9. }
  10. /**
  11. * 取一个区间内随机整数
  12. * @param n 开始位置
  13. * @param m 结束位置
  14. * @param ifInt 是否是整数
  15. * @returns 返回的随机整数
  16. */
  17. public random(n: number, m: number, ifInt: boolean = true): number {
  18. let random: number = n;
  19. if (ifInt) {
  20. random = Math.floor(Math.random() * (m - n + 1) + n);
  21. }
  22. else {
  23. random = Math.random() * (m - n) + n;
  24. }
  25. return random;
  26. }
  27. /**
  28. * 根据权重随机
  29. * @param weights 权重数组
  30. * @param total 权重总值 默认100
  31. * @param asc 权重为降序排列
  32. * @returns
  33. */
  34. public randomByWeight(weights: number[], total = 100, asc: boolean = true): number {
  35. if (total != 100) {
  36. total = 0;
  37. for (let i = 0; i < weights.length; i++) {
  38. total += weights[i];
  39. }
  40. }
  41. let random = Math.random() * total;
  42. let arr = weights.concat(random);
  43. arr = arr.sort((a, b) => {
  44. return asc ? a - b : b - a;
  45. });
  46. var randomIndex = arr.indexOf(random);
  47. randomIndex = Math.min(randomIndex, weights.length - 1);
  48. return randomIndex;
  49. }
  50. //---------------------------------------------------------科学计数法-----------------------------------------------------
  51. /**数字单位 */
  52. private numUnit = { 4: "万", 8: "亿", 12: "兆", 16: "万兆", 20: "亿兆", 24: "兆兆", 28: "万兆兆", 32: "亿兆兆", 36: "兆兆兆" };
  53. /**
  54. * 超大数值加法运算 忽略小数部分
  55. * @param a
  56. * @param b
  57. */
  58. public addition(a: string, b: string): string {
  59. var res: any = '',
  60. temp: any = 0;
  61. let a1 = a.split('.')[0].split('');
  62. let b1 = b.split('.')[0].split('');
  63. while (a1.length || b1.length || temp) {
  64. temp += ~~a1.pop() + ~~b1.pop();
  65. res = (temp % 10) + res;
  66. temp = temp > 9;
  67. }
  68. return res.replace(/^0+/, '');
  69. }
  70. /**
  71. * 超大数值减法运算 忽略小数部分
  72. * @param a
  73. * @param b
  74. */
  75. public subtraction(a: any, b: any): string {
  76. a = a.split('.')[0].split('');
  77. b = b.split('.')[0].split('');
  78. var aMaxb = a.length > b.length;
  79. if (a.length == b.length) {
  80. for (var i = 0, len = a.length; i < len; i++) {
  81. if (a[i] == b[i]) continue;
  82. aMaxb = a[i] > b[i];
  83. break;
  84. }
  85. }
  86. if (!aMaxb) a = [b, b = a][0];
  87. var result = '';
  88. while (a.length) {
  89. var temp = parseInt(a.pop()) - parseInt(b.pop() || 0);
  90. if (temp >= 0) result = temp + result;
  91. else {
  92. result = temp + 10 + result;
  93. a[a.length - 1]--;
  94. }
  95. }
  96. result = (aMaxb ? '' : '-') + result.replace(/^0*/g, '');
  97. if (result == '-') {
  98. result = '0'
  99. }
  100. return result
  101. }
  102. /**
  103. * 超大数值高位对比 忽略小数部分
  104. * @param a
  105. * @param b
  106. */
  107. public contrastNumber(a: any, b: any): boolean {
  108. a = a.split('.')[0].split('');
  109. b = b.split('.')[0].split('');
  110. var aMaxb = a.length > b.length;
  111. if (a.length == b.length) {
  112. for (var i = 0, len = a.length; i < len; i++) {
  113. if (a[i] == b[i]) continue;
  114. aMaxb = a[i] > b[i];
  115. break;
  116. }
  117. }
  118. if (!aMaxb) a = [b, b = a][0];
  119. var result = '';
  120. while (a.length) {
  121. var temp = parseInt(a.pop()) - parseInt(b.pop() || 0);
  122. if (temp >= 0) result = temp + result;
  123. else {
  124. result = temp + 10 + result;
  125. a[a.length - 1]--;
  126. }
  127. }
  128. if (a === b) return true;
  129. return Boolean(aMaxb);
  130. }
  131. /**
  132. * 数值乘法
  133. * @param a
  134. * @param b
  135. */
  136. public accMuls(a, b): string {
  137. let arra = a.split('').reverse(),
  138. arrb = b.split('').reverse(),
  139. lena = arra.length,
  140. lenb = arrb.length,
  141. result: any = Array(lena + lenb + 1).join('0').split('');
  142. arra.map((itema, indexa) => {
  143. arrb.map((itemb, indexb) => {
  144. result[indexa + indexb] = +result[indexa + indexb] + itema * itemb;
  145. });
  146. });
  147. result.map((item, index) => {
  148. if (item >= 10) {
  149. result[index + 1] = ~~result[index + 1] + ~~(result[index] / 10);
  150. result[index] %= 10;
  151. }
  152. });
  153. return result.reverse().join('').replace(/^0+/, '');
  154. }
  155. /**
  156. * 超大数值乘法
  157. * @param arg1
  158. * @param arg2
  159. */
  160. public accMul(arg1: string, arg2: string): string {
  161. var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
  162. try { m += s1.split(".")[1].length } catch (e) { }
  163. try { m += s2.split(".")[1].length } catch (e) { }
  164. let targe = this.accMuls(s1.replace(".", ""), s2.replace(".", ""));
  165. return this.accDiv(targe, Math.pow(10, m).toString())
  166. }
  167. /** 科学技术法转为数值字符串形式 */
  168. public toNonExponential(num: number): string {
  169. return num.toLocaleString().replace(/[,]/g, '')
  170. }
  171. /**
  172. * 超大数值除法运算
  173. * @param arg1
  174. * @param arg2
  175. */
  176. public accDiv(arg1: string, arg2: string): string {
  177. var t1 = 0, t2 = 0, t3 = 0, r1, r2;
  178. try { t1 = arg1.toString().split(".")[1].length } catch (e) { }
  179. try { t2 = arg2.toString().split(".")[1].length } catch (e) { }
  180. r1 = Number(arg1.toString().replace(".", ""))
  181. r2 = Number(arg2.toString().replace(".", ""))
  182. if (r2 == 0)
  183. return '0';
  184. var result = String(r1 / r2);
  185. try { t3 = result.toString().split(".")[1].length } catch (e) { }
  186. var index = t2 - t1 - t3;
  187. if (index < 0) {
  188. result = result.replace(".", "");
  189. while (result.length <= Math.abs(index)) {
  190. result = '0' + result;
  191. }
  192. var start = result.substring(0, result.length + index);
  193. var end = result.substring(result.length + index, result.length);
  194. result = start + '.' + end;
  195. return this.toNonExponential(Number(result));
  196. }
  197. else if (index > 0) {
  198. result = result.replace(".", "");
  199. while (result.length <= Math.abs(index)) {
  200. result += '0';
  201. }
  202. return this.toNonExponential(Number(result));
  203. }
  204. else return this.toNonExponential(Number(result.replace(".", "")));
  205. }
  206. /**
  207. * 数值格式化
  208. * @param value
  209. * @param showDeci
  210. */
  211. public format(value: string, showDeci: boolean = true): string {
  212. var a = value.split('.')[0];
  213. var b;
  214. for (let i in this.numUnit) {
  215. let ii = Number(i);
  216. if (a.length - 1 >= ii) {
  217. if (showDeci) {
  218. let deci = a.slice(a.length - ii, a.length - ii + 1)
  219. if (Number(deci) >= 1) {
  220. b = a.slice(0, a.length - ii) + "." + deci + this.numUnit[ii];
  221. }
  222. else {
  223. b = a.slice(0, a.length - ii) + this.numUnit[ii];
  224. }
  225. }
  226. else {
  227. b = a.slice(0, a.length - ii) + this.numUnit[ii];
  228. }
  229. }
  230. };
  231. if (!b) return a;
  232. return b;
  233. }
  234. }