<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Primality Checking</title>
	<atom:link href="http://programmingpraxis.com/2009/05/01/primality-checking/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2009/05/01/primality-checking/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Mon, 28 May 2012 03:30:45 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: David</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-4857</link>
		<dc:creator><![CDATA[David]]></dc:creator>
		<pubDate>Tue, 22 May 2012 12:03:42 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-4857</guid>
		<description><![CDATA[This is a Haskell program I wrote (ironically enough around May 2009, though I hadn&#039;t heard about this website back then.)  This was my first relatively non-trivial Haskell program.

[sourcecode language=&quot;text&quot;]
import System.Random
import System (getArgs)

-- return number N as (s,d) where N = (2^S)*d
pow2factor n
   &#124; odd n  = (0, n)
   &#124; even n = (s+1, d) where (s,d) = pow2factor (n `div` 2)

-- compute (a^n) (mod m)
--     (efficient algorithm, doing modulo arithmetic after each step)

square x = x*x

pow a 0 m = 1
pow a n m
   &#124; odd  n = (a * (pow a (n - 1) m)) `mod` m
   &#124; even n = (square (pow a (n `div` 2) m)) `mod` m


-- Miller-Rabin: given an integer n, determine if it is prime with
-- probability 4 ^ -k, where k is the number of tests performed.

probablyPrime n tests =
    let (s, d) = pow2factor (n-1) in not (any (\x -&gt; testComposite x s d) tests) where
	testComposite a s d =
	    (pow a d n) `notElem` [1, n-1] &amp;&amp;
	    all (\r -&gt; (pow a (r*d) n) /= n-1) (take (s-1) (iterate (2*) 2))
    

-- main

testPrime n =
    do rnd &lt;- newStdGen
       return (probablyPrime n (take 10 (randomRs (2, n-2) rnd)))

genprime :: Integer -&gt; IO Integer
genprime bits =
    do rnd &lt;- getStdGen
       thePrime &lt;- firstprime (randomRs (2, 2^(bits-1)) rnd)
       return thePrime where
           firstprime (h:t) =
	       let candidate = 2*h+1 in
		   do isPrime &lt;- testPrime candidate
		      if isPrime then return candidate else firstprime t

main =
   do args &lt;- getArgs
      case args of
	 [&quot;-g&quot;, bits] -&gt; do x &lt;- genprime ((read bits) :: Integer)
	                    putStrLn (show x)
	 [&quot;-t&quot;, n] -&gt; do isPrime &lt;- testPrime ((read n) :: Integer)
			 putStrLn (if isPrime then &quot;prime&quot; else &quot;composite&quot;)
	 otherwise -&gt; error &quot;Usage: miller-rabin [-g bits] [-t number]&quot;
[/sourcecode]

To test 2^89 -1 use,
.\miller-rabin.exe -t 618970019642690137449562111]]></description>
		<content:encoded><![CDATA[<p>This is a Haskell program I wrote (ironically enough around May 2009, though I hadn&#8217;t heard about this website back then.)  This was my first relatively non-trivial Haskell program.</p>
<pre class="brush: plain;">
import System.Random
import System (getArgs)

-- return number N as (s,d) where N = (2^S)*d
pow2factor n
   | odd n  = (0, n)
   | even n = (s+1, d) where (s,d) = pow2factor (n `div` 2)

-- compute (a^n) (mod m)
--     (efficient algorithm, doing modulo arithmetic after each step)

square x = x*x

pow a 0 m = 1
pow a n m
   | odd  n = (a * (pow a (n - 1) m)) `mod` m
   | even n = (square (pow a (n `div` 2) m)) `mod` m


-- Miller-Rabin: given an integer n, determine if it is prime with
-- probability 4 ^ -k, where k is the number of tests performed.

probablyPrime n tests =
    let (s, d) = pow2factor (n-1) in not (any (\x -&gt; testComposite x s d) tests) where
	testComposite a s d =
	    (pow a d n) `notElem` [1, n-1] &amp;&amp;
	    all (\r -&gt; (pow a (r*d) n) /= n-1) (take (s-1) (iterate (2*) 2))
    

-- main

testPrime n =
    do rnd &lt;- newStdGen
       return (probablyPrime n (take 10 (randomRs (2, n-2) rnd)))

genprime :: Integer -&gt; IO Integer
genprime bits =
    do rnd &lt;- getStdGen
       thePrime &lt;- firstprime (randomRs (2, 2^(bits-1)) rnd)
       return thePrime where
           firstprime (h:t) =
	       let candidate = 2*h+1 in
		   do isPrime &lt;- testPrime candidate
		      if isPrime then return candidate else firstprime t

main =
   do args &lt;- getArgs
      case args of
	 [&quot;-g&quot;, bits] -&gt; do x &lt;- genprime ((read bits) :: Integer)
	                    putStrLn (show x)
	 [&quot;-t&quot;, n] -&gt; do isPrime &lt;- testPrime ((read n) :: Integer)
			 putStrLn (if isPrime then &quot;prime&quot; else &quot;composite&quot;)
	 otherwise -&gt; error &quot;Usage: miller-rabin [-g bits] [-t number]&quot;
</pre>
<p>To test 2^89 -1 use,<br />
.\miller-rabin.exe -t 618970019642690137449562111</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matías Giovannini</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-3656</link>
		<dc:creator><![CDATA[Matías Giovannini]]></dc:creator>
		<pubDate>Sat, 24 Sep 2011 11:25:43 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-3656</guid>
		<description><![CDATA[I made a mistake in &lt;code&gt;random_big_int&lt;/code&gt;. Lines 10 and 11 are wrong, they should read:

[sourcecode lang=&quot;fsharp&quot;]
    shift_left_nat nat ofs 1 tmp 0 4;
    set_digit_nat tmp 0 (Random.bits () land 15);
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>I made a mistake in <code>random_big_int</code>. Lines 10 and 11 are wrong, they should read:</p>
<pre class="brush: fsharp;">
    shift_left_nat nat ofs 1 tmp 0 4;
    set_digit_nat tmp 0 (Random.bits () land 15);
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matías Giovannini</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-3646</link>
		<dc:creator><![CDATA[Matías Giovannini]]></dc:creator>
		<pubDate>Fri, 23 Sep 2011 18:57:18 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-3646</guid>
		<description><![CDATA[Wow, so much code needed in OCaml to solve this exercise in a self-contained fashion! First of all, a general-purpose function to return a  random &lt;code&gt;Big_int&lt;/code&gt; between 0 and a specified &lt;code&gt;max&lt;/code&gt; (exclusive):

[sourcecode lang=&quot;fsharp&quot;]
let random_big_int =
  let open Big_int in
  let open Nat in
  let random_limb = match length_of_digit with
  &#124; 64 -&gt; fun nat ofs tmp -&gt;
    set_digit_nat nat ofs (Random.bits ());
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits ());
    lor_digit_nat nat ofs tmp 0;
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits () land 7);
    lor_digit_nat nat ofs tmp 0
  &#124; 32 -&gt; fun nat ofs tmp -&gt;
    set_digit_nat nat ofs (Random.bits ());
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits () land 3);
    lor_digit_nat nat ofs tmp 0
  &#124; _  -&gt; assert false
  in fun max -&gt;
  let nat = nat_of_big_int max in
  let len = num_digits_nat nat 0 (length_nat nat) in
  let res = create_nat len
  and tmp = create_nat 1 in
  for i = 0 to len - 1 do random_limb res i tmp done;
  mod_big_int (big_int_of_nat res) max
[/sourcecode]

(You can&#039;t go much lower level than this.) Next, some utility functions on &lt;code&gt;Big_int&lt;/code&gt;s:

[sourcecode lang=&quot;fsharp&quot;]
let is_zero_big_int n = Big_int.sign_big_int n == 0

let is_even_big_int n = Big_int.( is_zero_big_int (and_big_int n unit_big_int) )

let modsquare_big_int x n = Big_int.( mod_big_int (square_big_int x) n)

let modexp_big_int x e n =
  let open Big_int in
  let rec go y z e =
    if is_zero_big_int e then y else
    let y = if is_even_big_int e
      then y
      else mod_big_int (mult_big_int y z) n
    in go y (modsquare_big_int z n) (shift_right_big_int e 1)
  in go unit_big_int x e
[/sourcecode]

Finally, an imperative-style Rabin-Miller test:

[sourcecode lang=&quot;fsharp&quot;]
let is_prime n =
  let open Big_int in
  if le_big_int n unit_big_int &#124;&#124; is_even_big_int n
    then invalid_arg &quot;is_prime&quot; else
  let m = pred_big_int n in
  let r = ref 0
  and s = ref m in
  while is_even_big_int !s do
    incr r;
    s := shift_right_big_int !s 1
  done;
  try for i = 1 to 50 do
    let a = add_int_big_int 2 (random_big_int (add_int_big_int (-2) n)) in
    let x = ref (modexp_big_int a !s n)
    and j = ref !r in
    let any = ref (eq_big_int !x unit_big_int) in
    while !j != 0 &amp;&amp; not !any do
      if eq_big_int !x m
        then any := true
        else x := modsquare_big_int !x n;
      decr j
    done;
    if not !any then raise Exit
  done;
  true
  with Exit -&gt; false
[/sourcecode]

Two optimizations were applied: first, the random a should be greater than 1; second, the successive powers of a in the inner loop are calculated inductively by (modular) squaring.]]></description>
		<content:encoded><![CDATA[<p>Wow, so much code needed in OCaml to solve this exercise in a self-contained fashion! First of all, a general-purpose function to return a  random <code>Big_int</code> between 0 and a specified <code>max</code> (exclusive):</p>
<pre class="brush: fsharp;">
let random_big_int =
  let open Big_int in
  let open Nat in
  let random_limb = match length_of_digit with
  | 64 -&gt; fun nat ofs tmp -&gt;
    set_digit_nat nat ofs (Random.bits ());
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits ());
    lor_digit_nat nat ofs tmp 0;
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits () land 7);
    lor_digit_nat nat ofs tmp 0
  | 32 -&gt; fun nat ofs tmp -&gt;
    set_digit_nat nat ofs (Random.bits ());
    shift_left_nat nat ofs 1 tmp 0 30;
    set_digit_nat tmp 0 (Random.bits () land 3);
    lor_digit_nat nat ofs tmp 0
  | _  -&gt; assert false
  in fun max -&gt;
  let nat = nat_of_big_int max in
  let len = num_digits_nat nat 0 (length_nat nat) in
  let res = create_nat len
  and tmp = create_nat 1 in
  for i = 0 to len - 1 do random_limb res i tmp done;
  mod_big_int (big_int_of_nat res) max
</pre>
<p>(You can&#8217;t go much lower level than this.) Next, some utility functions on <code>Big_int</code>s:</p>
<pre class="brush: fsharp;">
let is_zero_big_int n = Big_int.sign_big_int n == 0

let is_even_big_int n = Big_int.( is_zero_big_int (and_big_int n unit_big_int) )

let modsquare_big_int x n = Big_int.( mod_big_int (square_big_int x) n)

let modexp_big_int x e n =
  let open Big_int in
  let rec go y z e =
    if is_zero_big_int e then y else
    let y = if is_even_big_int e
      then y
      else mod_big_int (mult_big_int y z) n
    in go y (modsquare_big_int z n) (shift_right_big_int e 1)
  in go unit_big_int x e
</pre>
<p>Finally, an imperative-style Rabin-Miller test:</p>
<pre class="brush: fsharp;">
let is_prime n =
  let open Big_int in
  if le_big_int n unit_big_int || is_even_big_int n
    then invalid_arg &quot;is_prime&quot; else
  let m = pred_big_int n in
  let r = ref 0
  and s = ref m in
  while is_even_big_int !s do
    incr r;
    s := shift_right_big_int !s 1
  done;
  try for i = 1 to 50 do
    let a = add_int_big_int 2 (random_big_int (add_int_big_int (-2) n)) in
    let x = ref (modexp_big_int a !s n)
    and j = ref !r in
    let any = ref (eq_big_int !x unit_big_int) in
    while !j != 0 &amp;&amp; not !any do
      if eq_big_int !x m
        then any := true
        else x := modsquare_big_int !x n;
      decr j
    done;
    if not !any then raise Exit
  done;
  true
  with Exit -&gt; false
</pre>
<p>Two optimizations were applied: first, the random a should be greater than 1; second, the successive powers of a in the inner loop are calculated inductively by (modular) squaring.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Graham</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-3035</link>
		<dc:creator><![CDATA[Graham]]></dc:creator>
		<pubDate>Mon, 16 May 2011 19:49:37 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-3035</guid>
		<description><![CDATA[I&#039;m slowly working my way through old exercises now that I have some free time. &lt;a href=&quot;https://gist.github.com/975182&quot; rel=&quot;nofollow&quot;&gt;Here&#039;s&lt;/a&gt;
my attempt in Common Lisp; I&#039;m trying to learn the language, even though I already had Pythoned Miller-Rabin previously.]]></description>
		<content:encoded><![CDATA[<p>I&#8217;m slowly working my way through old exercises now that I have some free time. <a href="https://gist.github.com/975182" rel="nofollow">Here&#8217;s</a><br />
my attempt in Common Lisp; I&#8217;m trying to learn the language, even though I already had Pythoned Miller-Rabin previously.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jens Axel Søgaard</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-96</link>
		<dc:creator><![CDATA[Jens Axel Søgaard]]></dc:creator>
		<pubDate>Mon, 04 May 2009 18:49:35 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-96</guid>
		<description><![CDATA[&lt;pre&gt;#lang scheme
(require srfi/1   ; list-tabulate
         srfi/27) ; random-integer

(define (factor2 n)
  ; return r and s  s.t  n = 2^r * s where s is odd
  (let loop ([r 0] [s n])
    ; invariant: n = 2^r * s
    (let-values ([(q r) (quotient/remainder s 2)])
      (if (zero? r)
          (loop (+ r 1) q)
          (values r s)))))

(define (miller-rabin n)
  ; Input: n odd   Output: n prime?
  (define (mod x) (modulo x n))
  (define (^ x m) 
    (cond [(zero? m) 1]
          [(even? m) (mod (sqr (^ x (/ m 2))))]
          [(odd? m)  (mod (* x (^ x (- m 1))))]))
  (define (check? a)
    (let-values ([(r s) (factor2 (sub1 n))])
      (and (member (^ a s) (list 1 (mod -1))) #t)))
  (andmap check? 
          (list-tabulate 50 (Î» (_) (+ 2 (random-integer (- n 3)))))))

(define (prime? n)
  (cond [(&lt; n 2) #f]
        [(= n 2) #t]
        [(even? n) #f]
        [else (miller-rabin n)]))

(prime? (- (expt 2 89) 1))

&lt;/pre&gt;]]></description>
		<content:encoded><![CDATA[<pre>#lang scheme
(require srfi/1   ; list-tabulate
         srfi/27) ; random-integer

(define (factor2 n)
  ; return r and s  s.t  n = 2^r * s where s is odd
  (let loop ([r 0] [s n])
    ; invariant: n = 2^r * s
    (let-values ([(q r) (quotient/remainder s 2)])
      (if (zero? r)
          (loop (+ r 1) q)
          (values r s)))))

(define (miller-rabin n)
  ; Input: n odd   Output: n prime?
  (define (mod x) (modulo x n))
  (define (^ x m) 
    (cond [(zero? m) 1]
          [(even? m) (mod (sqr (^ x (/ m 2))))]
          [(odd? m)  (mod (* x (^ x (- m 1))))]))
  (define (check? a)
    (let-values ([(r s) (factor2 (sub1 n))])
      (and (member (^ a s) (list 1 (mod -1))) #t)))
  (andmap check? 
          (list-tabulate 50 (Î» (_) (+ 2 (random-integer (- n 3)))))))

(define (prime? n)
  (cond [(&lt; n 2) #f]
        [(= n 2) #t]
        [(even? n) #f]
        [else (miller-rabin n)]))

(prime? (- (expt 2 89) 1))

</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-93</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Fri, 01 May 2009 14:20:05 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-93</guid>
		<description><![CDATA[My Haskell solution (see http://bonsaicode.wordpress.com/2009/05/01/programming-praxis-primality-checking/ for a version with comments):

[sourcecode lang=&#039;css&#039;]
import Control.Arrow
import Data.Bits
import Data.List
import System.Random

isPrime :: Integer -&gt; StdGen -&gt; Bool
isPrime n g =
    let (s, d) = (length *** head) . span even $ iterate (flip div 2) (n - 1)
        xs = map (expm n d) . take 50 $ randomRs (2, n - 2) g
    in all (\x -&gt; elem x [1, n - 1] &#124;&#124;
                  any (== n - 1) (take s $ iterate (expm n 2) x)) xs

expm :: Integer -&gt; Integer -&gt; Integer -&gt; Integer
expm m e b = foldl&#039; (\r (b&#039;, _) -&gt; mod (r * b&#039;) m) 1 .
             filter (flip testBit 0 . snd) .
             zip (iterate (flip mod m . (^ 2)) b) $
             takeWhile (&gt; 0) $ iterate (flip shiftR 1) e

main :: IO ()
main = print . isPrime (2 ^ 89 - 1) =&lt;&lt; getStdGen
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution (see <a href="http://bonsaicode.wordpress.com/2009/05/01/programming-praxis-primality-checking/" rel="nofollow">http://bonsaicode.wordpress.com/2009/05/01/programming-praxis-primality-checking/</a> for a version with comments):</p>
<pre class="brush: css;">
import Control.Arrow
import Data.Bits
import Data.List
import System.Random

isPrime :: Integer -&gt; StdGen -&gt; Bool
isPrime n g =
    let (s, d) = (length *** head) . span even $ iterate (flip div 2) (n - 1)
        xs = map (expm n d) . take 50 $ randomRs (2, n - 2) g
    in all (\x -&gt; elem x [1, n - 1] ||
                  any (== n - 1) (take s $ iterate (expm n 2) x)) xs

expm :: Integer -&gt; Integer -&gt; Integer -&gt; Integer
expm m e b = foldl' (\r (b', _) -&gt; mod (r * b') m) 1 .
             filter (flip testBit 0 . snd) .
             zip (iterate (flip mod m . (^ 2)) b) $
             takeWhile (&gt; 0) $ iterate (flip shiftR 1) e

main :: IO ()
main = print . isPrime (2 ^ 89 - 1) =&lt;&lt; getStdGen
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Programming Praxis - Primality Checking &#171; Bonsai Code</title>
		<link>http://programmingpraxis.com/2009/05/01/primality-checking/#comment-92</link>
		<dc:creator><![CDATA[Programming Praxis - Primality Checking &#171; Bonsai Code]]></dc:creator>
		<pubDate>Fri, 01 May 2009 14:19:40 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=528#comment-92</guid>
		<description><![CDATA[[...] Praxis - Primality&#160;Checking By Remco Niemeijer  Today&#8217;s Programming Praxis problem is about checking whether or not a number is prime. We&#8217;re supposed [...]]]></description>
		<content:encoded><![CDATA[<p>[...] Praxis &#8211; Primality&nbsp;Checking By Remco Niemeijer  Today&#8217;s Programming Praxis problem is about checking whether or not a number is prime. We&#8217;re supposed [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

