6

I just tried to implement Fermat's little theorem in JavaScript. I tried it both ways, a^(p-1) mod p = 1 and a^p mod p = a mod p.

function fermat(a, p) {
  return (((a ^ (p - 1)) % p) === 1);
}

and

function fermat(a, p) {
  return ( ( a^p ) % p ) === ( a % p );
}

It doesn't work both ways, is there any way to fix that?

fb55
  • 1,197
  • 1
  • 11
  • 16

6 Answers6

9

In Javascript ^ means XOR. For exponentiation you need Math.pow(x, y).

function fermat(a, p) {
  return Math.pow(a, p - 1) % p === 1;
}
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
7

Instead of ^, you need to use Math.pow

Kiersten Arnold
  • 1,840
  • 1
  • 13
  • 17
3

In addition to the ^ vs. Math.pow() issue others have pointed out, the next hurdle you will likely face is the limited precision of the Javascript built-in numeric types. You will very quickly exceed the range of exactly representable Javascript numbers once the exponents start getting large, as they will be if you're wanting to use a routine like this as a primality test. You may want to look into a Javascript bignum library (for example, this one) that supports exponentiation and modulus for arbitrarily large integers.

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
  • yes, I know that. I already implemented Fermat's little theorem in Java and got an extremely fast response, but when I tried to get all primes up to 10k, I ran out of limits. But this is just for a test on jsperf (http://jsperf.com/prime-numbers/4), and it performs nearly as fast as some solutions using a cache (for half a million operation-loops). I'm fine with that result… – fb55 Aug 03 '10 at 20:58
2

In javascript, the carat (^) is the XOR operator. What you want to use is the Math.pow(x,y) function which is equivalent to x^y.

Mike Clark
  • 11,769
  • 6
  • 39
  • 43
0

Here is my code (JavaScript) for checking whether a number is prime based on Fermat Little Theorem.

    function getRandomInt(min,max) { /* getting a random between given max and min values */
        min = Math.ceil(min);
        max = Math.ceil(max);
        return Math.floor(Math.random()*(max-min))+min;
    }

    function getGCD(a,b) { /* getting the greatest common divisor */
        var tmp;
        while (b !== 0) {
            tmp = b;
            b = a%b;
            a = tmp;
        }
        return a;
    }

    function getPower(a,b,p) { /* getting the a^b mod p */
        if (b == 1)
         return a%p;
        else {
         x = getPower(a,Math.floor(b/2),p);
         if (b%2 == 0) 
          return (x*x)%p;
         else return (((x*x)%p)*a)%p;
        }
    }

    function fermatTesting(Num) { //Checking Num by using Fermat's theorem
        var a = getRandomInt(2,Num-1);
        if (getGCD(a,Num) !== 1) {
            return "COMPOSITE";
        }
        else {
            if (getPower(a,Num-1,Num) !== 1) {
                return "COMPOSITE";
            }
            else {
                return "PRIME"; 
            }
        }
    }

    console.log(fermatTesting(57)); //Displays "COMPOSITE"
0

There's nothing like answering an eleven year old question!

Since it's now 2021 we have support for BigInt, which supports arbitrary precision along with the exponentiation operator (**) and the modulus operator(%).

The function in the accepted answer can be rewritten as

function fermat(a, p) {
    return (a**(p-1n) % p) === 1n;
}

where a and p are BigInt values.