Why Modular Exponentiation functions work differen

2019-07-23 12:37发布

I need to perform modular exponentiation on quite large numbers on both python3 and javascript. I have functions that do the task, but they give me different outputs.

Python (all of the three work in the same way):

pow(176672119508, 55, 200000023499)

def expmod_iter(a,b,c):
    x = 1
    while(b>0):
        if(b&1==1): x = (x*a)%c
        a=(a*a)%c
        b >>= 1
    return x%c

def pow_mod(x, y, z):
    number = 1
    while y:
        if y & 1:
            number = number * x % z
        y >>= 1
        x = x * x % z
    return number

# The result is always 124912252967

and now JavaScript (both functions work in the same way):

function powMod(x, y, z) {
  let number = 1;
  while (y) {
      if (y & 1) {
          number = number * x % z;
      }
      y >>= 1;
      x = x * x % z;
  }
  return number;
}

function expmod_iter(a, b, c) {
  let x = 1;

  while (b > 0) {
    if (b & 1 === 1) {
      x = (x * a) % c;
    }
    a = (a * a) % c;
    b >>= 1
  }
  return x % c;
}

console.log(powMod(176672119508, 55, 200000023499));
console.log(expmod_iter(176672119508, 55, 200000023499));

// The result is always 138693107570

And moreover, when I used this service with my numbers, I also got 138693107570.


Why does this happen? I'm not even sure what variant is correct now. However, on smaller numbers the functions give identical results.

Is it possible to somehow get the same result from the functions? It doesn't even matter that much that the result is mathematically correct, the results should be at least the same.

Could you please explain why this happens? Is it the function design? To me, functions on both languages seem to be identical.

Is there a way to get the same result from functions of both languages?

1条回答
时光不老,我们不散
2楼-- · 2019-07-23 13:20

Python's result is correct.

Python uses an arbitrary-precision integer representation, while Javascript stores all numbers as IEEE754 64-bit floating point (and temporarily coerces them to 32-bit integers for bitwise operations). This means that for large integers, the Javascript code starts losing precision, while the Python code maintains the exact values of all results throughout the calculation.

If you want to handle large integers exactly in Javascript, you will need to use an appropriate library. Alternatively, you say you don't care much about the result being correct. That is a really weird thing to not care about, but if you really feel that way:

# Python
def wrongpow(a, b, c):
    return 0

// Javascript
function wrongpow(a, b, c) {
    return 0;
}
查看更多
登录 后发表回答