# Logarithmic run time for calculating prime numbers?

Here's the function I'm currently analyzing. I know it's not the most optimal but I'm not understanding the $$\theta()$$ of this algorithm. I've been told that it's not actually $$\theta(n)$$ but instead a logarithmic run-time and it had something to do with the bits of the value passed in. I'm not understanding how the bits are causing the logarithmic so if someone can explain that it'd be great.

   function isPrime(n):
1  if n = 2 return true
2  for i from 2 to n
3      if n % i = 0 return false
4  return true


Let's use a different parameter for your input, $$m$$. The number of instructions that your algorithm executes in the worst case is $$O(m)$$.

We often measure the running time of algorithms in terms of the length of their input (measured either in bits or in words), often denoted by $$n$$. The length of your input is $$n \approx \log_2 m$$, since this is how long it takes to encode the integer $$m$$ in binary. Therefore your algorithm actually performs an exponential number of instructions $$O(2^n)$$.

A different issue is the cost of arithmetic operations, such as the modulo operation on line 3. In most models of computation (and in real life), the cost of such an operation depends on the length of the numbers being operated on. Therefore your algorithm runs in time which is worse than $$2^n$$ by a polynomial factor $$n^{O(1)}$$ (the exact polynomial factor depends on the algorithm you use to perform the division). Such a running time is usually denoted $$\tilde{O}(2^n)$$.

• So does O(m) have anything to do with the O(2^n) at all or are they just 2 ways of measuring the algorithm. And how does the encoding work exactly, I didn't think it was necessary to count from 0 all the way to n in binary – Justin Li Oct 4 '18 at 20:53
• These are two ways to measure the running time. As for the encoding, it’s really an implementation detail. – Yuval Filmus Oct 5 '18 at 0:24

Well, first, the algorithm is incorrect: it claims that every integer less than or equal to $$2$$ is prime, and every integer greater than $$2$$ is composite.

• Any $$n\leq1$$ fails the test at line $$1$$, does zero iterations of the loope at lines $$2$$$$3$$ and returns true at line $$4$$.
• $$n=2$$ triggers the return true on line $$1$$.
• Any $$n>2$$ fails the test at line $$1$$. If it is composite, it returns false at line $$3$$ for its smallest prime factor; if it is prime, then the loop will get as far as $$i=n$$, at which point the n%i=0 is true, so we return false at line $$3$$.

So, suppose we correct line $$2$$ to be for i=2 to n-1 and assume the input is greater than $$1$$. Then, for any prime input $$n>2$$, the loop at lines $$2$$$$3$$ will run for each value $$2, \dots, n-1$$, which is $$n-2 = \Theta(n)$$ iterations. So your suspicion that the running time is $$\Theta(n)$$ is correct: this algorithm is not logarithmic.

In general, as Yuval explains, we measure the running time of algorithms in terms of the length of the input as written in binary. Since the number $$n$$ takes $$\Theta(\log n)$$ bits to write down, and the running time of the algorithm is $$\Theta(n) = \Theta(2^{\text{input length}})$$, this algorithm would normally be described as having exponential running time.