arithmetic.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.absNumber = absNumber;
  6. exports.addNumber = addNumber;
  7. exports.cbrtNumber = cbrtNumber;
  8. exports.cubeNumber = cubeNumber;
  9. exports.divideNumber = divideNumber;
  10. exports.expNumber = expNumber;
  11. exports.expm1Number = expm1Number;
  12. exports.gcdNumber = gcdNumber;
  13. exports.lcmNumber = lcmNumber;
  14. exports.log10Number = log10Number;
  15. exports.log1pNumber = log1pNumber;
  16. exports.log2Number = log2Number;
  17. exports.logNumber = logNumber;
  18. exports.modNumber = modNumber;
  19. exports.multiplyNumber = multiplyNumber;
  20. exports.normNumber = normNumber;
  21. exports.nthRootNumber = nthRootNumber;
  22. exports.powNumber = powNumber;
  23. exports.roundNumber = roundNumber;
  24. exports.signNumber = signNumber;
  25. exports.sqrtNumber = sqrtNumber;
  26. exports.squareNumber = squareNumber;
  27. exports.subtractNumber = subtractNumber;
  28. exports.unaryMinusNumber = unaryMinusNumber;
  29. exports.unaryPlusNumber = unaryPlusNumber;
  30. exports.xgcdNumber = xgcdNumber;
  31. var _number = require("../../utils/number.js");
  32. var n1 = 'number';
  33. var n2 = 'number, number';
  34. function absNumber(a) {
  35. return Math.abs(a);
  36. }
  37. absNumber.signature = n1;
  38. function addNumber(a, b) {
  39. return a + b;
  40. }
  41. addNumber.signature = n2;
  42. function subtractNumber(a, b) {
  43. return a - b;
  44. }
  45. subtractNumber.signature = n2;
  46. function multiplyNumber(a, b) {
  47. return a * b;
  48. }
  49. multiplyNumber.signature = n2;
  50. function divideNumber(a, b) {
  51. return a / b;
  52. }
  53. divideNumber.signature = n2;
  54. function unaryMinusNumber(x) {
  55. return -x;
  56. }
  57. unaryMinusNumber.signature = n1;
  58. function unaryPlusNumber(x) {
  59. return x;
  60. }
  61. unaryPlusNumber.signature = n1;
  62. function cbrtNumber(x) {
  63. return (0, _number.cbrt)(x);
  64. }
  65. cbrtNumber.signature = n1;
  66. function cubeNumber(x) {
  67. return x * x * x;
  68. }
  69. cubeNumber.signature = n1;
  70. function expNumber(x) {
  71. return Math.exp(x);
  72. }
  73. expNumber.signature = n1;
  74. function expm1Number(x) {
  75. return (0, _number.expm1)(x);
  76. }
  77. expm1Number.signature = n1;
  78. /**
  79. * Calculate gcd for numbers
  80. * @param {number} a
  81. * @param {number} b
  82. * @returns {number} Returns the greatest common denominator of a and b
  83. */
  84. function gcdNumber(a, b) {
  85. if (!(0, _number.isInteger)(a) || !(0, _number.isInteger)(b)) {
  86. throw new Error('Parameters in function gcd must be integer numbers');
  87. }
  88. // https://en.wikipedia.org/wiki/Euclidean_algorithm
  89. var r;
  90. while (b !== 0) {
  91. r = a % b;
  92. a = b;
  93. b = r;
  94. }
  95. return a < 0 ? -a : a;
  96. }
  97. gcdNumber.signature = n2;
  98. /**
  99. * Calculate lcm for two numbers
  100. * @param {number} a
  101. * @param {number} b
  102. * @returns {number} Returns the least common multiple of a and b
  103. */
  104. function lcmNumber(a, b) {
  105. if (!(0, _number.isInteger)(a) || !(0, _number.isInteger)(b)) {
  106. throw new Error('Parameters in function lcm must be integer numbers');
  107. }
  108. if (a === 0 || b === 0) {
  109. return 0;
  110. }
  111. // https://en.wikipedia.org/wiki/Euclidean_algorithm
  112. // evaluate lcm here inline to reduce overhead
  113. var t;
  114. var prod = a * b;
  115. while (b !== 0) {
  116. t = b;
  117. b = a % t;
  118. a = t;
  119. }
  120. return Math.abs(prod / a);
  121. }
  122. lcmNumber.signature = n2;
  123. /**
  124. * Calculate the logarithm of a value, optionally to a given base.
  125. * @param {number} x
  126. * @param {number | null | undefined} base
  127. * @return {number}
  128. */
  129. function logNumber(x, y) {
  130. if (y) {
  131. return Math.log(x) / Math.log(y);
  132. }
  133. return Math.log(x);
  134. }
  135. /**
  136. * Calculate the 10-base logarithm of a number
  137. * @param {number} x
  138. * @return {number}
  139. */
  140. function log10Number(x) {
  141. return (0, _number.log10)(x);
  142. }
  143. log10Number.signature = n1;
  144. /**
  145. * Calculate the 2-base logarithm of a number
  146. * @param {number} x
  147. * @return {number}
  148. */
  149. function log2Number(x) {
  150. return (0, _number.log2)(x);
  151. }
  152. log2Number.signature = n1;
  153. /**
  154. * Calculate the natural logarithm of a `number+1`
  155. * @param {number} x
  156. * @returns {number}
  157. */
  158. function log1pNumber(x) {
  159. return (0, _number.log1p)(x);
  160. }
  161. log1pNumber.signature = n1;
  162. /**
  163. * Calculate the modulus of two numbers
  164. * @param {number} x
  165. * @param {number} y
  166. * @returns {number} res
  167. * @private
  168. */
  169. function modNumber(x, y) {
  170. if (y > 0) {
  171. // We don't use JavaScript's % operator here as this doesn't work
  172. // correctly for x < 0 and x === 0
  173. // see https://en.wikipedia.org/wiki/Modulo_operation
  174. return x - y * Math.floor(x / y);
  175. } else if (y === 0) {
  176. return x;
  177. } else {
  178. // y < 0
  179. // TODO: implement mod for a negative divisor
  180. throw new Error('Cannot calculate mod for a negative divisor');
  181. }
  182. }
  183. modNumber.signature = n2;
  184. /**
  185. * Calculate the nth root of a, solve x^root == a
  186. * http://rosettacode.org/wiki/Nth_root#JavaScript
  187. * @param {number} a
  188. * @param {number} [2] root
  189. * @private
  190. */
  191. function nthRootNumber(a) {
  192. var root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
  193. var inv = root < 0;
  194. if (inv) {
  195. root = -root;
  196. }
  197. if (root === 0) {
  198. throw new Error('Root must be non-zero');
  199. }
  200. if (a < 0 && Math.abs(root) % 2 !== 1) {
  201. throw new Error('Root must be odd when a is negative.');
  202. }
  203. // edge cases zero and infinity
  204. if (a === 0) {
  205. return inv ? Infinity : 0;
  206. }
  207. if (!isFinite(a)) {
  208. return inv ? 0 : a;
  209. }
  210. var x = Math.pow(Math.abs(a), 1 / root);
  211. // If a < 0, we require that root is an odd integer,
  212. // so (-1) ^ (1/root) = -1
  213. x = a < 0 ? -x : x;
  214. return inv ? 1 / x : x;
  215. // Very nice algorithm, but fails with nthRoot(-2, 3).
  216. // Newton's method has some well-known problems at times:
  217. // https://en.wikipedia.org/wiki/Newton%27s_method#Failure_analysis
  218. /*
  219. let x = 1 // Initial guess
  220. let xPrev = 1
  221. let i = 0
  222. const iMax = 10000
  223. do {
  224. const delta = (a / Math.pow(x, root - 1) - x) / root
  225. xPrev = x
  226. x = x + delta
  227. i++
  228. }
  229. while (xPrev !== x && i < iMax)
  230. if (xPrev !== x) {
  231. throw new Error('Function nthRoot failed to converge')
  232. }
  233. return inv ? 1 / x : x
  234. */
  235. }
  236. function signNumber(x) {
  237. return (0, _number.sign)(x);
  238. }
  239. signNumber.signature = n1;
  240. function sqrtNumber(x) {
  241. return Math.sqrt(x);
  242. }
  243. sqrtNumber.signature = n1;
  244. function squareNumber(x) {
  245. return x * x;
  246. }
  247. squareNumber.signature = n1;
  248. /**
  249. * Calculate xgcd for two numbers
  250. * @param {number} a
  251. * @param {number} b
  252. * @return {number} result
  253. * @private
  254. */
  255. function xgcdNumber(a, b) {
  256. // source: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
  257. var t; // used to swap two variables
  258. var q; // quotient
  259. var r; // remainder
  260. var x = 0;
  261. var lastx = 1;
  262. var y = 1;
  263. var lasty = 0;
  264. if (!(0, _number.isInteger)(a) || !(0, _number.isInteger)(b)) {
  265. throw new Error('Parameters in function xgcd must be integer numbers');
  266. }
  267. while (b) {
  268. q = Math.floor(a / b);
  269. r = a - q * b;
  270. t = x;
  271. x = lastx - q * x;
  272. lastx = t;
  273. t = y;
  274. y = lasty - q * y;
  275. lasty = t;
  276. a = b;
  277. b = r;
  278. }
  279. var res;
  280. if (a < 0) {
  281. res = [-a, -lastx, -lasty];
  282. } else {
  283. res = [a, a ? lastx : 0, lasty];
  284. }
  285. return res;
  286. }
  287. xgcdNumber.signature = n2;
  288. /**
  289. * Calculates the power of x to y, x^y, for two numbers.
  290. * @param {number} x
  291. * @param {number} y
  292. * @return {number} res
  293. */
  294. function powNumber(x, y) {
  295. // x^Infinity === 0 if -1 < x < 1
  296. // A real number 0 is returned instead of complex(0)
  297. if (x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity) {
  298. return 0;
  299. }
  300. return Math.pow(x, y);
  301. }
  302. powNumber.signature = n2;
  303. /**
  304. * round a number to the given number of decimals, or to zero if decimals is
  305. * not provided
  306. * @param {number} value
  307. * @param {number} decimals number of decimals, between 0 and 15 (0 by default)
  308. * @return {number} roundedValue
  309. */
  310. function roundNumber(value) {
  311. var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  312. if (!(0, _number.isInteger)(decimals) || decimals < 0 || decimals > 15) {
  313. throw new Error('Number of decimals in function round must be an integer from 0 to 15 inclusive');
  314. }
  315. return parseFloat((0, _number.toFixed)(value, decimals));
  316. }
  317. /**
  318. * Calculate the norm of a number, the absolute value.
  319. * @param {number} x
  320. * @return {number}
  321. */
  322. function normNumber(x) {
  323. return Math.abs(x);
  324. }
  325. normNumber.signature = n1;