number-precision.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. var NP = (function (exports) {
  2. 'use strict';
  3. /**
  4. * @desc 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。
  5. * 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998
  6. */
  7. /**
  8. * 把错误的数据转正
  9. * strip(0.09999999999999998)=0.1
  10. */
  11. function strip(num, precision) {
  12. if (precision === void 0) { precision = 12; }
  13. return +parseFloat(num.toPrecision(precision));
  14. }
  15. /**
  16. * Return digits length of a number
  17. * @param {*number} num Input number
  18. */
  19. function digitLength(num) {
  20. // Get digit length of e
  21. var eSplit = num.toString().split(/[eE]/);
  22. var len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0));
  23. return len > 0 ? len : 0;
  24. }
  25. function powLength(num) {
  26. var eSplit = num.toString().split(/[eE]/);
  27. var rs = num.toString().reverse();
  28. var rs1 = rs.replace('/^0+/g', '');
  29. return rs.length - rs1.length;
  30. }
  31. /**
  32. * 把小数转成整数,支持科学计数法。如果是小数则放大成整数
  33. * @param {*number} num 输入数
  34. */
  35. function float2Fixed(num) {
  36. if (num.toString().indexOf('e') === -1) {
  37. return Number(num.toString().replace('.', ''));
  38. }
  39. var dLen = digitLength(num);
  40. return dLen > 0 ? strip(num * Math.pow(10, dLen)) : num;
  41. }
  42. /**
  43. * 检测数字是否越界,如果越界给出提示
  44. * @param {*number} num 输入数
  45. */
  46. function checkBoundary(num) {
  47. if (_boundaryCheckingState) {
  48. if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
  49. console.warn(num + " is beyond boundary when transfer to integer, the results may not be accurate");
  50. }
  51. }
  52. }
  53. /**
  54. * 精确乘法
  55. */
  56. function times(num1, num2) {
  57. var others = [];
  58. for (var _i = 2; _i < arguments.length; _i++) {
  59. others[_i - 2] = arguments[_i];
  60. }
  61. if (others.length > 0) {
  62. return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1)));
  63. }
  64. var num1Changed = float2Fixed(num1);
  65. var num2Changed = float2Fixed(num2);
  66. var baseNum = digitLength(num1) + digitLength(num2);
  67. var leftValue = num1Changed * num2Changed;
  68. checkBoundary(leftValue);
  69. return leftValue / Math.pow(10, baseNum);
  70. }
  71. /**
  72. * 精确加法
  73. */
  74. function plus(num1, num2) {
  75. var others = [];
  76. for (var _i = 2; _i < arguments.length; _i++) {
  77. others[_i - 2] = arguments[_i];
  78. }
  79. if (others.length > 0) {
  80. return plus.apply(void 0, [plus(num1, num2), others[0]].concat(others.slice(1)));
  81. }
  82. var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
  83. return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
  84. //return (num1 + num2) / baseNum;
  85. }
  86. /**
  87. * 精确减法
  88. */
  89. function minus(num1, num2) {
  90. var others = [];
  91. for (var _i = 2; _i < arguments.length; _i++) {
  92. others[_i - 2] = arguments[_i];
  93. }
  94. if (others.length > 0) {
  95. return minus.apply(void 0, [minus(num1, num2), others[0]].concat(others.slice(1)));
  96. }
  97. var digit1 = digitLength(num1);
  98. var digit2 = digitLength(num2);
  99. var baseNum = Math.pow(10, Math.max(digit1, digit2));
  100. return round((times(num1, baseNum) - times(num2, baseNum)) / baseNum, digit1>=digit2 ? digit1 : digit2);
  101. }
  102. /**
  103. * 精确除法
  104. */
  105. function divide(num1, num2) {
  106. var others = [];
  107. for (var _i = 2; _i < arguments.length; _i++) {
  108. others[_i - 2] = arguments[_i];
  109. }
  110. if (others.length > 0) {
  111. return divide.apply(void 0, [divide(num1, num2), others[0]].concat(others.slice(1)));
  112. }
  113. var num1Changed = float2Fixed(num1);
  114. var num2Changed = float2Fixed(num2);
  115. checkBoundary(num1Changed);
  116. checkBoundary(num2Changed);
  117. return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1)));
  118. }
  119. /**
  120. * 四舍五入
  121. */
  122. function round(num, ratio) {
  123. var base = Math.pow(10, ratio);
  124. return divide(Math.round(times(num, base)), base);
  125. }
  126. var _boundaryCheckingState = true;
  127. /**
  128. * 是否进行边界检查,默认开启
  129. * @param flag 标记开关,true 为开启,false 为关闭,默认为 true
  130. */
  131. function enableBoundaryChecking(flag) {
  132. if (flag === void 0) { flag = true; }
  133. _boundaryCheckingState = flag;
  134. }
  135. var index = { strip: strip, plus: plus, minus: minus, times: times, divide: divide, round: round, digitLength: digitLength, float2Fixed: float2Fixed, enableBoundaryChecking: enableBoundaryChecking };
  136. exports.strip = strip;
  137. exports.plus = plus;
  138. exports.minus = minus;
  139. exports.times = times;
  140. exports.divide = divide;
  141. exports.round = round;
  142. exports.digitLength = digitLength;
  143. exports.float2Fixed = float2Fixed;
  144. exports.enableBoundaryChecking = enableBoundaryChecking;
  145. exports['default'] = index;
  146. return exports;
  147. }({}));
  148. function transFormToChinese(num) {
  149. const changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
  150. const unit = ["", "十", "百", "千", "万"];
  151. num = parseInt(num);
  152. let getWan = (temp) => {
  153. let strArr = temp.toString().split("").reverse();
  154. let newNum = "";
  155. for (var i = 0; i < strArr.length; i++) {
  156. newNum = (i == 0 && strArr[i] == 0 ? "" : (i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 ? "" : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i]))) + newNum;
  157. }
  158. return strArr.length === 2 && newNum.indexOf("一十") !== -1 ? newNum.replace('一十', '十') : newNum;
  159. }
  160. let overWan = Math.floor(num / 10000);
  161. let noWan = num % 10000;
  162. if (noWan.toString().length < 4) noWan = "0" + noWan;
  163. return overWan ? getWan(overWan) + "万" + getWan(noWan) : getWan(num);
  164. }