<?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>Sat, 11 Feb 2012 09:48:16 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<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>

