-1
$\begingroup$

I'm trying to write a procedure that solves (2^n - 1) mod 1000000007 for a given n.

n can be very large (~10^9).

Say m = 1000000007

So this is what I have so far:

func(n):
  if n = 1 return 2
  if n is even return ((func(n/2) mod m)^2)mod m
  else return ((func(n/2) mod m)^2 * 2)mod m

I'll call func and subtract 1 from the result to get the final answer.

Is it right to use that recursion?

$\endgroup$
3
  • 1
    $\begingroup$ More generally $ab\bmod m=(a\bmod{m})(b\bmod{m})\bmod m$. $\endgroup$ Commented Nov 1, 2013 at 20:43
  • $\begingroup$ For the case even and odd you are recursing func(n/2). Is / and integer division or a floating point division? If it is not integer then the end condition will not be met. $\endgroup$ Commented Nov 1, 2013 at 20:45
  • $\begingroup$ Please learn the difference between binary mod (that gives the remainder) and a congruence (a bidirectional comparison operator). $5\bmod 2$ is an instance of binary mod and returns an integer (here $1$). If you use the TeX-command \pmod it means a congruence: like $2\equiv7\pmod5$. That (in programming parlance) is a comparison operator taking a T/F value. In this case it evaluates to true because $2-7=-5$ is a multiple of $5$. Notation such as $(2\pmod 5)^2$ is non-sensical (should result in a parsing error), because it is trying to square an incorrectly defined boolean variable :-). $\endgroup$ Commented Nov 1, 2013 at 21:28

2 Answers 2

1
$\begingroup$

If you are asking whether $(2^{n/2})^2 \equiv 2^n \pmod{m}$ then the answer is yes, since they are already equal as integers, so they will be equal after you pass to the residue classes. There is no need to drag the symbol "mod" along everywhere in your title. Just put it at the end of the congruence.

By the way, the multiplicative order of $2$ in $\mathbb{Z}/1000000007\mathbb{Z}$ is $500000003$. So let $r$ be the remainder after division of $n$ by $500000003$, and we'll have $2^n \equiv 2^r \pmod{1000000007}$. That is probably the most efficient way to it.

$\endgroup$
0
$\begingroup$

I've done it in lisp, but it could easily be done in a conventional language.

(defun mod97 (x)
       (mod x 1000000007))

(defun simple (exxp)
    "Do (2^exp) mod 1000000007 
     as if you didn't have to worry about overflow and such."
    (mod97 (expt 2 exxp)))

(defun 2expmod (exxp)
    "do (2^exxp) mod 1000000007 even if it would normally overflow"
    (cond
        ((< exxp 10)   ; is exponent small enough to not worry about overflow
         (simple exxp))
        ((evenp exxp)  ; break the 2^(2n) into (2^n)^2
         (mod97 (expt (2expmod (/ exxp 2)) 2)))
        (t             ; otherwise break 2^(2n+1) into 2*2^(2n)
         (mod97 (* 2 (2expmod (1- exxp)))))))
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .