isPrime.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createIsPrime = void 0;
  6. var _collection = require("../../utils/collection.js");
  7. var _factory = require("../../utils/factory.js");
  8. var name = 'isPrime';
  9. var dependencies = ['typed'];
  10. var createIsPrime = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  11. var typed = _ref.typed;
  12. /**
  13. * Test whether a value is prime: has no divisors other than itself and one.
  14. * The function supports type `number`, `bignumber`.
  15. *
  16. * The function is evaluated element-wise in case of Array or Matrix input.
  17. *
  18. * Syntax:
  19. *
  20. * math.isPrime(x)
  21. *
  22. * Examples:
  23. *
  24. * math.isPrime(3) // returns true
  25. * math.isPrime(-2) // returns false
  26. * math.isPrime(0) // returns false
  27. * math.isPrime(-0) // returns false
  28. * math.isPrime(0.5) // returns false
  29. * math.isPrime('2') // returns true
  30. * math.isPrime([2, 17, 100]) // returns [true, true, false]
  31. *
  32. * See also:
  33. *
  34. * isNumeric, isZero, isNegative, isInteger
  35. *
  36. * @param {number | BigNumber | Array | Matrix} x Value to be tested
  37. * @return {boolean} Returns true when `x` is larger than zero.
  38. * Throws an error in case of an unknown data type.
  39. */
  40. return typed(name, {
  41. number: function number(x) {
  42. if (x * 0 !== 0) {
  43. return false;
  44. }
  45. if (x <= 3) {
  46. return x > 1;
  47. }
  48. if (x % 2 === 0 || x % 3 === 0) {
  49. return false;
  50. }
  51. for (var i = 5; i * i <= x; i += 6) {
  52. if (x % i === 0 || x % (i + 2) === 0) {
  53. return false;
  54. }
  55. }
  56. return true;
  57. },
  58. BigNumber: function BigNumber(n) {
  59. if (n.toNumber() * 0 !== 0) {
  60. return false;
  61. }
  62. if (n.lte(3)) return n.gt(1);
  63. if (n.mod(2).eq(0) || n.mod(3).eq(0)) return false;
  64. if (n.lt(Math.pow(2, 32))) {
  65. var x = n.toNumber();
  66. for (var i = 5; i * i <= x; i += 6) {
  67. if (x % i === 0 || x % (i + 2) === 0) {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. function modPow(base, exponent, modulus) {
  74. // exponent can be huge, use non-recursive variant
  75. var accumulator = 1;
  76. while (!exponent.eq(0)) {
  77. if (exponent.mod(2).eq(0)) {
  78. exponent = exponent.div(2);
  79. base = base.mul(base).mod(modulus);
  80. } else {
  81. exponent = exponent.sub(1);
  82. accumulator = base.mul(accumulator).mod(modulus);
  83. }
  84. }
  85. return accumulator;
  86. }
  87. // https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants
  88. var Decimal = n.constructor.clone({
  89. precision: n.toFixed(0).length * 2
  90. });
  91. n = new Decimal(n);
  92. var r = 0;
  93. var d = n.sub(1);
  94. while (d.mod(2).eq(0)) {
  95. d = d.div(2);
  96. r += 1;
  97. }
  98. var bases = null;
  99. // https://en.wikipedia.org/wiki/Miller–Rabin_primality_test#Testing_against_small_sets_of_bases
  100. if (n.lt('3317044064679887385961981')) {
  101. bases = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41].filter(function (x) {
  102. return x < n;
  103. });
  104. } else {
  105. var max = Math.min(n.toNumber() - 2, Math.floor(2 * Math.pow(n.toFixed(0).length * Math.log(10), 2)));
  106. bases = [];
  107. for (var _i = 2; _i <= max; _i += 1) {
  108. bases.push(max);
  109. }
  110. }
  111. for (var _i2 = 0; _i2 < bases.length; _i2 += 1) {
  112. var a = bases[_i2];
  113. var adn = modPow(n.sub(n).add(a), d, n);
  114. if (!adn.eq(1)) {
  115. for (var _i3 = 0, _x = adn; !_x.eq(n.sub(1)); _i3 += 1, _x = _x.mul(_x).mod(n)) {
  116. if (_i3 === r - 1) {
  117. return false;
  118. }
  119. }
  120. }
  121. }
  122. return true;
  123. },
  124. 'Array | Matrix': typed.referToSelf(function (self) {
  125. return function (x) {
  126. return (0, _collection.deepMap)(x, self);
  127. };
  128. })
  129. });
  130. });
  131. exports.createIsPrime = createIsPrime;