Search code examples
javascriptnode.jsfunctionprimesfactorial

JS function to detect primes not working correctly


I'm trying to make a function to determine if a number is prime on JS. The method I'm using for this is the Wilson's theorem, which states that, in short, if (num - 1)! % num is equal to num -1, then num is prime. To implement this function I made another function to calculate the factorial of a given number. I also added a conditional operator to return false if the given number is smaller or equal than 1, to fulfill a condition of prime numbers.

The factorial function works just fine (I checked its return values), but for some reason, the Wilson's theorem function has issues. I worked trough a lot of primes and determined that below 23 the function will work, and above 29 (the first prime after 23) the function won't (including 29).

Now, I know that there are much simpler ways to implement a function that serves this purpose, yet I want to try to use the Wilson's theroem and really don't understand why this function doesn't work. Below you can se my code and the tests I made for the function. Please leave a comment if you notice any problems that my code might have or if you know any way I could improve my functions to reach higher optimization or to solve my problem. Thanks in advance.

// Factorial function
let factorial = function(num) {
  let outp = 1;
  for (let i = 1; i <= num; i++) {
      outp *= i;
  }
  return outp;
}

// Prime tester function
let isPrime = x => x <= 1 ? false : factorial(x-1) % x == x-1;

// Test function
console.log(isPrime(7));  // Should return: true, returns: true
console.log(isPrime(23));  // Should return: true, returns: true
console.log(isPrime(29));  // Should return: true, returns: false
console.log(isPrime(101));  // Should return: true, returns: false

If it is relevant, I am using node.js, but I also tested it on online compilers and observed no difference.


Solution

  • Modern versions of Javascript support arbitrary precision integers (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt), which can be used to compute large integers exactly:

    // Factorial function
    let factorial = function (num) {
        let outp = 1n; // the `n` suffix indicates a `BigInt` constant
        for (let i = 1n; i <= num; i++) {
            outp *= i;
        }
        return outp;
    }
    
    // Prime tester function
    let isPrime = x => x <= 1n ? false : factorial(x - 1n) % x == x - 1n;
    
    // Test function
    console.log(isPrime(7n));  
    console.log(isPrime(23n)); 
    console.log(isPrime(29n)); 
    console.log(isPrime(101n));