scMathUtil.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * Created by jimiz on 2017/3/28.
  3. */
  4. let scMathUtil = {
  5. innerRoundTo: function(num, digit){
  6. let lFactor = Math.pow(10, digit);
  7. let fOffSet = 0.5;
  8. let sign = '';
  9. // 处理符号
  10. if (num < 0){
  11. sign = '-';
  12. num = Math.abs(num);
  13. }
  14. // 计算
  15. let result = Math.floor((num / lFactor) + fOffSet).toString();
  16. let iLength = result.length;
  17. // 因为数值被转为整数计算,当目标位数在小数点后,且数值小于0,需要补齐前面的位数
  18. if (iLength < -digit){
  19. result = this.zeroString(-digit) + result;
  20. }
  21. // 当目标位数在小数点前,需要补齐后面的位数
  22. else if ((digit > 0) && (iLength < digit)){
  23. result = result + this.zeroString(digit);
  24. }
  25. iLength = result.length;
  26. // 获得小数点前的数字
  27. let r1 = result.substring(0, iLength + digit);
  28. // 获得小数点后的数字
  29. let r2 = result.substring(iLength + digit, iLength);
  30. // 拼出完整结果
  31. return Number(sign + r1 + '.' + r2);
  32. },
  33. floatToBin: function(num) {
  34. return num.toString(2);
  35. },
  36. binToFloat: function(bin) {
  37. let result = 0;
  38. let iLength = bin.length;
  39. let sign = '';
  40. if (iLength > 0 && bin[0]==='-'){
  41. sign = '-';
  42. bin = bin.substring(1, iLength);
  43. }
  44. iLength = bin.length;
  45. let iDot = bin.indexOf('.');
  46. if (iDot >= 0) {
  47. for (let i = 0; i < iLength; i++) {
  48. let num = Number(bin[i]);
  49. let idx = iDot - i;
  50. if (idx === 0) {
  51. continue
  52. };
  53. if (idx > 0) {
  54. idx -= 1
  55. };
  56. let r = Math.pow(2, idx);
  57. result += num * r;
  58. }
  59. }
  60. else {
  61. result = parseInt(bin, 2);
  62. };
  63. return sign + result;
  64. },
  65. zeroString: function(length){
  66. let result = '';
  67. for (let i = 0; i < length; i++){
  68. result = result + '0';
  69. };
  70. return result;
  71. },
  72. incMantissa: function(bin){
  73. let result = bin;
  74. let iDot = bin.indexOf('.');
  75. if (iDot < 0){return result};
  76. // 二进制浮点数带小数位数最大长度
  77. let floatLength = 53;
  78. let iLength = bin.length;
  79. // 长度小于53说明该二进制数尾数长度小于Double类型限制,未被截断,无需进位
  80. if (iLength < floatLength) {
  81. return result;
  82. }
  83. iLength = bin.length;
  84. for (let i = iLength - 1; i > iDot; i--){
  85. let num = Number(bin[i]);
  86. if (num === 0){
  87. num = 1;
  88. let bin1 = bin.substring(0, i);
  89. let bin2 = this.zeroString(iLength - (i + 1));//bin.substring(i + 1, iLength);
  90. result = bin1 + num.toString() + bin2;
  91. break;
  92. }
  93. };
  94. return result;
  95. },
  96. roundTo: function(num, digit){
  97. let me = this;
  98. return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
  99. },
  100. isNumber : function (obj) {
  101. return obj === +obj;
  102. },
  103. roundToString:function(obj,decimal){
  104. let me = this;
  105. let value;
  106. if(me.isNumber(obj)){
  107. value = me.roundTo(obj,-decimal)
  108. }else {
  109. value = me.roundTo(Number(obj),-decimal);
  110. }
  111. return value.toFixed(decimal);
  112. }
  113. };
  114. Number.prototype.toDecimal = function (ADigit) {
  115. //return parseFloat(this.toFixed(ADigit));
  116. digit = (ADigit && typeof(ADigit) === 'number' && Number.isInteger(ADigit) && ADigit >= 0) ? -ADigit : -2;
  117. // var s = scMathUtil.roundTo(this, digit);
  118. // console.log('Number: ' + this + ' Digit: ' + digit + ' Result: ' + s);
  119. // return parseFloat(s);
  120. return scMathUtil.roundTo(this, digit);
  121. };