arithmetic.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /**
  2. * @fileOverview 一些公用的运算方法
  3. * @author xile611
  4. * @date 2015-09-17
  5. */
  6. import Decimal from 'decimal.js-light';
  7. import { curry } from './utils';
  8. /**
  9. * 获取数值的位数
  10. * 其中绝对值属于区间[0.1, 1), 得到的值为0
  11. * 绝对值属于区间[0.01, 0.1),得到的位数为 -1
  12. * 绝对值属于区间[0.001, 0.01),得到的位数为 -2
  13. *
  14. * @param {Number} value 数值
  15. * @return {Integer} 位数
  16. */
  17. function getDigitCount(value) {
  18. var result;
  19. if (value === 0) {
  20. result = 1;
  21. } else {
  22. result = Math.floor(new Decimal(value).abs().log(10).toNumber()) + 1;
  23. }
  24. return result;
  25. }
  26. /**
  27. * 按照固定的步长获取[start, end)这个区间的数据
  28. * 并且需要处理js计算精度的问题
  29. *
  30. * @param {Decimal} start 起点
  31. * @param {Decimal} end 终点,不包含该值
  32. * @param {Decimal} step 步长
  33. * @return {Array} 若干数值
  34. */
  35. function rangeStep(start, end, step) {
  36. var num = new Decimal(start);
  37. var i = 0;
  38. var result = []; // magic number to prevent infinite loop
  39. while (num.lt(end) && i < 100000) {
  40. result.push(num.toNumber());
  41. num = num.add(step);
  42. i++;
  43. }
  44. return result;
  45. }
  46. /**
  47. * 对数值进行线性插值
  48. *
  49. * @param {Number} a 定义域的极点
  50. * @param {Number} b 定义域的极点
  51. * @param {Number} t [0, 1]内的某个值
  52. * @return {Number} 定义域内的某个值
  53. */
  54. var interpolateNumber = curry(function (a, b, t) {
  55. var newA = +a;
  56. var newB = +b;
  57. return newA + t * (newB - newA);
  58. });
  59. /**
  60. * 线性插值的逆运算
  61. *
  62. * @param {Number} a 定义域的极点
  63. * @param {Number} b 定义域的极点
  64. * @param {Number} x 可以认为是插值后的一个输出值
  65. * @return {Number} 当x在 a ~ b这个范围内时,返回值属于[0, 1]
  66. */
  67. var uninterpolateNumber = curry(function (a, b, x) {
  68. var diff = b - +a;
  69. diff = diff || Infinity;
  70. return (x - a) / diff;
  71. });
  72. /**
  73. * 线性插值的逆运算,并且有截断的操作
  74. *
  75. * @param {Number} a 定义域的极点
  76. * @param {Number} b 定义域的极点
  77. * @param {Number} x 可以认为是插值后的一个输出值
  78. * @return {Number} 当x在 a ~ b这个区间内时,返回值属于[0, 1],
  79. * 当x不在 a ~ b这个区间时,会截断到 a ~ b 这个区间
  80. */
  81. var uninterpolateTruncation = curry(function (a, b, x) {
  82. var diff = b - +a;
  83. diff = diff || Infinity;
  84. return Math.max(0, Math.min(1, (x - a) / diff));
  85. });
  86. export default {
  87. rangeStep: rangeStep,
  88. getDigitCount: getDigitCount,
  89. interpolateNumber: interpolateNumber,
  90. uninterpolateNumber: uninterpolateNumber,
  91. uninterpolateTruncation: uninterpolateTruncation
  92. };