Posted By

rolandog on 10/12/08


Tagged

javascript math ecmascript


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

rolandog


Math.js


 / Published in: JavaScript
 

URL: http://rolandog.com/math-js/

An ECMAScript library that adds some basic Mathematical functions to the Math object.

  1. /**
  2.  * Math.js
  3.  * http://rolandog.com/math-js/
  4.  *
  5.  * License: Creative Commons Attribution-Share Alike 3.0 Unported.
  6.  * http://creativecommons.org/licenses/by-sa/3.0/
  7.  *
  8.  * @projectDescription A library with Mathematical functions.
  9.  * @author Rolando Garza [email protected]
  10.  */
  11.  
  12. "use strict";
  13.  
  14. /**
  15.  * An extension to the Array object that filters out repeated values.
  16.  * @return(Array) Returns the filtered array.
  17.  */
  18. if (Array.unique !== undefined) {
  19. Array.prototype.unique = function Array_unique() {
  20. var a = [], l = this.length, i = 0, j;
  21. while (i < l) {
  22. for (j = i + 1; j < l; j += 1) {
  23. if (this[i] === this[j]) {
  24. i += 1;
  25. j = i;
  26. }
  27. }
  28. a.push(this[i]);
  29. i += 1;
  30. }
  31. return a;
  32. };
  33. }
  34.  
  35. /**
  36.  * An extension to the Array object that counts the instances of 'a'.
  37.  * @return(Number) Counts how many 'a' there are in the Array.
  38.  */
  39. if (Array.count !== undefined) {
  40. Array.prototype.count = function Array_count(a) {
  41. var r = 0, i;
  42. for (i = 0; i < this.length; i += 1) {
  43. r += this[i] === a ? 1 : 0;
  44. }
  45. return r;
  46. };
  47. }
  48.  
  49. /**
  50.  * @classDescription Contains some helpful functions.
  51.  */
  52. Math.js = {
  53. /**
  54.   * Duplicates argument objects or arrays, and returns them as arrays.
  55.   * @param(Object) as An Object or an Array.
  56.   * @return(Array) A duplicated array.
  57.   */
  58. copy: function Math_js_copy(as) {
  59. var a = 0, r = [];
  60. try {
  61. while (a < as.length) {
  62. r.push(as[a]);
  63. a += 1;
  64. }
  65. } catch (e) {
  66. for (a in as) {
  67. if (as.hasOwnProperty(a) && as[a]) {
  68. r.push(a);
  69. }
  70. }
  71. }
  72. return r;
  73. },
  74. /**
  75.   * Sorts an array of numbers in ascending order properly.
  76.   * @param(Number) a A Number.
  77.   * @param(Number) b A Number.
  78.   * @return(Number) The comparison between those numbers.
  79.   */
  80. ascending: function Math_js_ascending(a, b) {
  81. return a - b;
  82. },
  83. /**
  84.   * Sorts an array of numbers in descending order properly.
  85.   * @param(Number) a A Number.
  86.   * @param(Number) b A Number.
  87.   * @return(Number) The comparison between those numbers.
  88.   */
  89. descending: function Math_js_descending(a, b) {
  90. return b - a;
  91. }
  92. };
  93.  
  94. /**
  95.  * An extension to the Math object that accepts Arrays or Numbers
  96.  * as an argument and returns the sum of all numbers.
  97.  * @param(Array) a A Number or an Array of numbers.
  98.  * @return(Number) Returns the sum of all numbers.
  99.  */
  100. Math.sum = function Math_sum(a) {
  101. var r = 0;
  102. a = a.length ? a:Math.js.copy(arguments);
  103. while (a.length) {
  104. r += a.shift();
  105. }
  106. return r;
  107. };
  108.  
  109. /**
  110.  * An extension to the Math object that accepts Arrays or Numbers
  111.  * as an argument and returns the product of all numbers.
  112.  * @param(Array) a A Number or an Array of numbers.
  113.  * @return(Number) Returns the product of all numbers.
  114.  */
  115. Math.product = function Math_product(a) {
  116. var r = 1;
  117. a = a.length ? a:Math.js.copy(arguments);
  118. while (a.length) {
  119. r *= a.shift();
  120. }
  121. return r;
  122. };
  123.  
  124. /**
  125.  * An extension to the Math object that accepts a Number
  126.  * and returns the factorial.
  127.  * @param(Array) a A Number or an Array of numbers.
  128.  * @return(Number) Returns the product of all numbers.
  129.  */
  130. Math.factorial = function Math_factorial(a) {
  131. return (a <= 1) ? 1 : a * Math.factorial(a - 1);
  132. };
  133.  
  134. /**
  135.  * Returns the Greatest Common Divisor using Euclid's algorithm.
  136.  * @param(Array) a An Array of integers.
  137.  * @return(Number) Returns the Greatest Common Divisor.
  138.  */
  139. Math.gcd = function Math_gcd(a) {
  140. a = a.length ? a:Math.js.copy(arguments);
  141. var l = a.length;
  142. if (l < 2) {
  143. throw "Error: Must have at least two integers.";
  144. }
  145. while (l - 2) {
  146. a.push(Math.gcd(a.shift(), a.shift()));
  147. l = a.length;
  148. }
  149. return a[1] === 0 ? a[0] : Math.gcd(a[1], a[0] % a[1]);
  150. };
  151.  
  152. /**
  153.  * Returns the Least Common Multiple.
  154.  * @param(Array) a An integer or an Array of integers.
  155.  * @return(Number) Returns the Least Common Multiple.
  156.  */
  157. Math.lcm = function Math_lcm(a) {
  158. a = a.length ? a:Math.js.copy(arguments);
  159. var l = a.length;
  160. while (l - 2) {
  161. a.unshift(Math.lcm(a.shift(), a.shift()));
  162. l = a.length;
  163. }
  164. return a[0] * a[1] / Math.gcd(a[0], a[1]);
  165. };
  166.  
  167. /**
  168.  * Determines if a number is prime.
  169.  * @param(Number) a An integer.
  170.  * @return(Boolean) true if a number is prime.
  171.  */
  172. Math.isPrime = function Math_isPrime(n) {
  173. if (n !== Math.floor(n) || n <= 1 || (n % 2 === 0 && n !== 2)) {
  174. return false;
  175. }
  176. if (n > 4) {
  177. var i, r = Math.ceil(Math.sqrt(n));
  178. for (i = 3; i <= r; i += 2) {
  179. if (n % i === 0) {
  180. return false;
  181. }
  182. }
  183. }
  184. return true;
  185. };
  186.  
  187. /**
  188.  * Returns the factors of a number in an array.
  189.  * @param(Number) a An integer.
  190.  * @return(Array) Returns the factors of 'a' in an array.
  191.  */
  192. Math.factors = function Math_factors(a) {
  193. var n = Math.abs(a), r = Math.floor(Math.sqrt(n)), i = 2, f = [];
  194. while (i <= n && i <= r) {
  195. if (n % i === 0) {
  196. f.push(i);
  197. n /= i;
  198. }
  199. else {
  200. i += 1;
  201. }
  202. }
  203. if (a !== Math.abs(a)) {
  204. f.unshift(-1);
  205. }
  206. return f;
  207. };
  208.  
  209. /**
  210.  * Returns the divisors of a number in an array.
  211.  * @param(Number) a An integer.
  212.  * @param(Boolean) b If true, returns the 'proper' divisors.
  213.  * @return(Array) Returns the divisors of 'a' in an array.
  214.  */
  215. Math.divisors = function Math_divisors(a, b) {
  216. var n = Math.abs(a), r = Math.sqrt(n), i = 1, d = [];
  217. while (i <= r) {
  218. if (a % i === 0) {
  219. d.push(i);
  220. if (i !== r) {
  221. d.push(a / i);
  222. }
  223. }
  224. i += 1;
  225. }
  226. d = d.sort(Math.js.ascending);
  227. if (b) {
  228. d.pop();
  229. }
  230. return d;
  231. };
  232.  
  233. /**
  234.  * Returns a Fibonacci sequence in an array.
  235.  * @param(Number) l The upper limit.
  236.  * @param(Number) a The starting value.
  237.  * @param(Number) b The next value in the sequence.
  238.  * @return(Array) Returns the sequence of Fibonacci numbers.
  239.  */
  240. Math.fibonacci = function Math_fibonacci(l, a, b) {
  241. a = a === undefined ? 1:a;
  242. b = b === undefined ? 2:b;
  243. var r = [a, b];
  244. while (r[r.length - 1] < l) {
  245. r.push(r[r.length - 1] + r[r.length - 2]);
  246. }
  247. return r;
  248. };
  249.  
  250. /**
  251.  * @classDescription Some big Integer functions
  252.  */
  253. Math.bigInt = {};
  254.  
  255. /**
  256.  * Returns big Integer factorial numbers
  257.  */
  258. Math.bigInt.factorial = function Math_bigInt_factorial(a) {
  259. var b = a.toString(), i, j, k, l, o, t, c;
  260. b = b.split("").reverse();
  261. for (i = 0; i < b.length; i += 1) {
  262. b[i] = parseInt(b[i], 10);
  263. }
  264. for (i = a - 1; i >= 2; i -= 1) {
  265. l = b.length;
  266. for (j = 0; j < l; j += 1) {
  267. b[j] *= i;
  268. }
  269. for (j = 0; j < l; j += 1) {
  270. t = b[j].toString().split("").reverse().join("");
  271. o = t.length;
  272. for (k = 0; k < o; k += 1) {
  273. c = parseInt(t.charAt(k), 10);
  274. b[j + k] = b[j + k] ? (k ? b[j + k] : 0) + c:c;
  275. }
  276. }
  277. }
  278. return b.reverse().join("");
  279. };
  280. /**
  281.  * Returns the sum of big Integers
  282.  */
  283. Math.bigInt.sum = function Math_bigInt_sum(a) {
  284. function flip(z) {
  285. z = typeof(z) === "string" ? z : "" + z;
  286. z = z.split("").reverse();
  287. for (var i = 0; i < z.length; i += 1) {
  288. z[i] = parseInt(z[i], 10);
  289. }
  290. return z;
  291. }
  292. function sum(A, B) {
  293. var C = [], i, l = Math.max(A.length, B.length);
  294. for (i = 0; i < l; i += 1) {
  295. C[i] = (A[i]?A[i]:0) + (B[i]?B[i]:0) + (C[i]?C[i]:0);
  296. if (C[i] >= 10) {
  297. C[i] -= 10;
  298. C[i + 1] = C[i + 1] ? C[i + 1] + 1 : 1;
  299. }
  300. }
  301. return C;
  302. }
  303. a = a.length && typeof(a) !== "string" ? a:Math.js.copy(arguments);
  304. var b = a.shift();
  305. b = flip(b);
  306. while (a.length) {
  307. b = sum(b, flip(a.shift()));
  308. }
  309. return b.reverse().join("");
  310. };
  311. Math.bigInt.multiply = function Math_bigInt_multiply(a) {
  312. function toInt(z) {
  313. for (var i = 0; i < z.length; i += 1) {
  314. z[i] = parseInt(z[i], 10);
  315. }
  316. return z;
  317. }
  318. function check(x) {
  319. var i, t, z = Math.js.copy(x).reverse();
  320. for (i = 0; i < z.length; i += 1) {
  321. if (z[i] >= 10) {
  322. t = parseInt(z[i] / 10, 10);
  323. z[i] = z[i] % 10;
  324. z[i + 1] = z[i + 1] !== undefined ? z[i + 1] + t : t;
  325. }
  326. }
  327. z.reverse();
  328. while (z[0] === 0) {
  329. z.shift();
  330. }
  331. return z.length !== 0 ? z : [0];
  332. }
  333. function fillz(z) {
  334. var r = [];
  335. while (z > 0) {
  336. r.push(0);
  337. z -= 1;
  338. }
  339. return r;
  340. }
  341. function product(f, g) {
  342. var i, j, k, r = [], t, u, z;
  343. for (j = g.length - 1; j >= 0; j -= 1) {
  344. t = [];
  345. //multiplies everything
  346. for (i = f.length - 1; i >= 0; i -= 1) {
  347. t[i] = f[i] * g[j];
  348. }
  349. //fills an array with zeros, according to the magnitude order of the number
  350. z = fillz(g.length - j - 1);
  351. //checks that every number in the array is below 10.
  352. u = check(t);
  353. //joins the number array and the zeros, and converts to string..
  354. t = u.concat(z);
  355. t = t.join("");
  356. r.unshift(t);
  357. }
  358. return toInt(Math.bigInt.sum(r).split(""));
  359. }
  360. a = a.length && typeof(a) !== "string" ? a:Math.js.copy(arguments);
  361. var b = a.shift(), c;
  362. b = toInt(("" + b).split(""));
  363. while (a.length) {
  364. c = toInt(("" + a.shift()).split(""));
  365. b = product(b, c);
  366. }
  367. return b.length ? b.join("") : "0";
  368. };
  369. //The limit of integer precision: parseInt("9007199254740994", 10)

Report this snippet  

You need to login to post a comment.