0% found this document useful (0 votes)
35 views23 pages

Primality Testing Algorithms Guide

Uploaded by

cheweiziii
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views23 pages

Primality Testing Algorithms Guide

Uploaded by

cheweiziii
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 23

國立臺南大學資訊工程學系

資工三「演算法」課程
第一次作業

題目: Primality Testing

班級 : 資工三
姓名 : 林哲維
學號 : S11159025

老師:陳宗禧

中華民國 113 年 10 月 07 日
目錄
(一) 簡 介 及 問 題 描 述 … … … .……………..…………………………………………1
1. 簡 介 … … … … … .…………………………………………………………………………2
2. 問 題 … … … … … … … … … … .……………………………………………………………4
(二) 理 論 分 析 … .………………………..………………………………………8
(三) 演 算 法 則 … .…………………………..……………………………………10
(四) 程 式 設 計 環 境 架 構 .………………………..…………………………………12
(五) 程 式 .…………………………………………..………………………………14
(六) 執 行 結 果 、 討 論 與 心 得 .………………………..……………………………18

參考文獻………………………………………………………….…………………22

-2-
(一) 簡介及問題描述
設計與實作三種質數測試 (Primality test)演算法,理論驗證與實驗分析該問題!

1. 簡介

求 Prime(n)? 首先定義 一整數 n,判斷 n 是質數 or 合成數? …

質數是指大於 1 的自然數,且只能被 1 和自身整除的數字。合成數則是大於 1 的自然數,但有其他的整除因子。質數在數學和計算機科學中具


有重要的地位,特別是在密碼學和數論中。質數的分布和特性吸引了許多數學家進行深入研究。

對於一個整數 n,質數測試的目的是確定𝑛是否為質數。這個問題可以通過不同的算法進行解決,這些算法各自有不同的計算複雜度和準確性。
以下將介紹四種常見的質數測試算法,並對其進行理論驗證與實驗分析。

2. 問題

Prime(n)問題定義:

求 Prime(n),實作與分析
i. Basic Prime Testing
ii. Fermat Primality Testing
iii. Miller-Rabin Primality Testing
iv. Sieve of Eratosthenes
v. Mersenne Prime Number discovery 2m-1

-3-
(二) 理論分析
1. Basic Prime Testing 理論
This is an approach that goes in a way to convert definition of prime numbers
to code. It checks if any of the number less than a given number(N) divides the
number or not. But on observing the factors of any number, this method can be
limited to check only till √N. This is because, product of any two numbers
greater than √N can never be equal to N
2. Fermat Primality Testing 理論
(1) Repeat following k times:
(a) Pick a randomly in the range [2, n - 2]
(b) If gcd(a, n) ? 1, then return false
(c) If an-1 ≢ 1 (mod n), then return false
(2) Return true [probably prime].
3. Miller-Rabin Primality Testing 理論
bool isPrime(int n, int k)
(1) Handle base cases for n < 3
(2) If n is even, return false.
(3) Find an odd number d such that n-1 can be written as d*2r.
Note that since n is odd, (n-1) must be even and r must be
greater than 0.
(4) Do following k times
if (millerTest(n, d) == false)
return false
(5) Return true.
This function is called for all k trials. It returns false if n is composite and
returns true if n is probably prime. d is an odd number such that d*2r = n-1 for
some r>=1

bool millerTest(int n, int d)


(1) Pick a random number 'a' in range [2, n-2]
(2) Compute: x = pow(a, d) % n
(3) If x == 1 or x == n-1, return true.
Below loop mainly runs 'r-1' times.
(4) Do following while d doesn't become n-1.
(a) x = (x*x) % n.
(b) If (x == 1) return false.
(c) If (x == n-1) return true.
4. Sieve of Eratosthenes 理論

-4-
The sieve of Eratosthenes is one of the most efficient ways to find all primes
smaller than n when n is smaller than 10 million or so.
Following is the algorithm to find all the prime numbers less than or equal to a
given integer n by the Eratosthene’s method:
When the algorithm terminates, all the numbers in the list that are not marked
are prime.

-5-
(三) 演算法則
1. 第一個演算法(Algorithm)

int PrimeTest(int N)

for (int i = 2; i*i <= N; ++i)

if(N%i == 0)

return 0;

return 1;

i. 演算法時間複雜度(time complexity)

O(√N)

演算法空間複雜度(space complexity)

O(1)

2. 第二個演算法(Algorithm)

function: FermatPrimalityTesting(int N):

pick a random integer k //not too less. not too high.

LOOP: repeat k times:

-6-
pick a random integer X in range (1,N-1)

if(X^(N-1)%N != 1):

return composite

return probably prime

i. 演算法時間複雜度(time complexity)

O(k \cdot \log N)

ii. 演算法空間複雜度(space complexity)

O(1)

3 第三個演算法(Algorithm)

function: MillerRabin_PrimalityTesting(int N):

if N%2 = 0:

return composite

write N-1 as (2^R . D) where D is odd number

pick a random integer k //not too less. not too high.

LOOP: repeat k times:

pick a random integer A in range [2,N-2]

X = A^D % N

if X = 1 or X = N-1:

continue LOOP

for i from 1 to r-1:

X = X^2 % N

-7-
if X = 1:

return composite

if X = N-1:

continue LOOP

return composite

return probably prime

i. 演算法時間複雜度(time complexity)

O(k \cdot \log N)…

ii. 演算法空間複雜度(space complexity)

O(1)

4. 第四個演算法

A[N] = {0}

for i from 2 to sqrt(N):

if A[i] = 0:

for j from 2 to N:

if i*j > N:

break

A[i*j] = 1

i. 演算法時間複雜度(time complexity)

O(N \log N)

ii. 演算法空間複雜度(space complexity)

O(N)

-8-
(四) 程式設計環境架構
程式設計語言、工具、環境與電腦硬體等規格說明…

1. 程式語言

C++

2. 程式開發工具

Visual Studio 2019

3. 電腦硬體

CPU: Intel i7,

Main Memory: 24GB

-9-
(五) 程式 (含 source code, input code, and output code)
程式含 source code, input code, and output code 等…

1. 主程式
1.BASIC

#include <iostream>

#include <cmath>

using namespace std;

// Function to check if a number is prime

bool isPrime(long long N)

if (N <= 1) {

return false;

if (N == 2 || N == 3) {

return true;

if (N % 2 == 0 || N % 3 == 0) {

return false;

for (long long i = 5; i * i <= N; i += 6) {

if (N % i == 0 || N % (i + 2) == 0) {

return false;

return true;

-10-
}

int main()

int T;

cout << "enter how many cases you want to test : ";

cin >> T; // Number of test cases

for (int t = 0; t < T; t++)

long long N;

cin >> N; // Read the number for each test case

if (isPrime(N)) {

cout << "prime" << endl;

else {

cout << "composite" << endl;

return 0;

system("pause");

2. FERMAT

#include <iostream>

#include <cstdlib>

#include <ctime>

using namespace std;


-11-
// Function to perform modular exponentiation (X^Y % N)

long long mod_exp(long long base, long long exp, long long mod) {

long long result = 1;

base = base % mod;

while (exp > 0) {

if (exp % 2 == 1) // If exp is odd, multiply base with result

result = (result * base) % mod;

exp = exp >> 1; // Divide exp by 2

base = (base * base) % mod; // Square the base

return result;

// Fermat Primality Test function

string fermat_primality_test(long long N, int k = 5)

// Handle small cases

if (N <= 1) return "composite";

if (N == 2 || N == 3) return "prime";

// Perform the test k times

for (int i = 0; i < k; i++) {

-12-
long long X = 2 + rand() % (N - 3); // Random integer X in range [2, N-2]

if (mod_exp(X, N - 1, N) != 1)

return "composite";

return "prime";

int main() {

srand(time(0)); // Seed for random number generator

int T; // Number of test cases

cout << "enter how many cases you want to test : ";

cin >> T;

for (int i = 0; i < T; i++) {

long long N;

cin >> N;

cout << fermat_primality_test(N) << endl;

return 0;

3. MILLER

#include <iostream>

-13-
#include <cstdlib>

#include <ctime>

using namespace std;

// Function to perform modular exponentiation

// It returns (x^y) % p

long long power(long long x, long long y, long long p) {

long long res = 1; // Initialize result

x = x % p; // Update x if it is more than or equal to p

while (y > 0) {

// If y is odd, multiply x with the result

if (y & 1)

res = (res * x) % p;

// y must be even now

y = y >> 1; // y = y/2

x = (x * x) % p; // Change x to x^2

return res;

// This function is called for all k trials.

// It returns false if n is composite and returns true if n is probably prime.

// d is an odd number such that d*2^r = n-1 for some r >= 1.

-14-
bool millerTest(long long n, long long d) {

// Pick a random number in [2..n-2]

// Corner cases make sure that n > 4

long long a = 2 + rand() % (n - 4);

// Compute a^d % n

long long x = power(a, d, n);

if (x == 1 || x == n - 1)

return true;

// Keep squaring x while one of the following doesn't happen:

// (i) d does not reach n-1

// (ii) (x^2) % n is not 1

// (iii) (x^2) % n is not n-1

while (d != n - 1) {

x = (x * x) % n;

d *= 2;

if (x == 1) return false;

if (x == n - 1) return true;

// Return composite

return false;

-15-
// It returns false if n is composite and returns true if n is probably prime.

// k is an input parameter that determines the accuracy level. Higher value of k means more
accuracy.

bool isPrime(long long n, int k) {

// Handle base cases

if (n <= 1 || n == 4) return false;

if (n <= 3) return true;

// Find d such that n-1 = d * 2^r

long long d = n - 1;

while (d % 2 == 0)

d /= 2;

// Perform k iterations of the Miller-Rabin test

for (int i = 0; i < k; i++)

if (!millerTest(n, d))

return false;

return true;

int main() {

srand(time(0)); // Seed for random number generation

int T; // Number of test cases

-16-
cout << "enter how many cases you want to test : ";

cin >> T;

while (T--) {

long long N;

cin >> N;

// Number of iterations for Miller-Rabin test

int accuracy = 5;

if (isPrime(N, accuracy))

cout << "prime" << endl;

else

cout << "composite" << endl;

return 0;

4. SIEVE

#include <iostream>

#include <vector>

#include <cmath>

using namespace std;

vector<bool> sieve_of_eratosthenes(long long limit) {

-17-
vector<bool> is_prime(limit + 1, true);

is_prime[0] = is_prime[1] = false; // 0 and 1 are not prime

for (long long i = 2; i * i <= limit; i++) {

if (is_prime[i]) {

for (long long j = i * i; j <= limit; j += i) {

is_prime[j] = false;

return is_prime;

bool is_prime(long long n) {

if (n <= 1) return false;

if (n <= 3) return true;

if (n % 2 == 0 || n % 3 == 0) return false;

for (long long i = 5; i * i <= n; i += 6) {

if (n % i == 0 || n % (i + 2) == 0) return false;

return true;

int main() {

int T;

-18-
cout << "enter how many cases you want to test : ";

cin >> T;

while (T--) {

long long N;

cin >> N;

if (N <= 10000000) { // Use sieve for smaller numbers

vector<bool> primes = sieve_of_eratosthenes(N);

if (primes[N]) {

cout << "prime" << endl;

else {

cout << "composite" << endl;

else { // Use direct primality check for larger numbers

if (is_prime(N)) {

cout << "prime" << endl;

else {

cout << "composite" << endl;

-19-
return 0;

2. Input Code Format

Three of examples for input use are in below….

(1) 3

(2) 122

(3) 5

(4) 3

3. Output Code Format

Three of examples for output use are in below….

(1) composite

(2) prime

(3) prime

-20-
(五) 執行結果、討論與心得
1. 執行結果

input use are in below….

(1) 3

(2) 122

(3) 5

(4) 3

output use are in below….

(1) composite

(2) prime

(3) prime

2. 討論

方法 2 和 3 機率:

(ii) FERMAT:

對於某些合數,費馬測試會錯誤地標記它們為質數,這些數稱為「費馬偽質數」。例如,561 是一個費馬偽質數。根據 𝑘 的選擇,成功率會


有所不同。

(iii) MILLER:

𝑘 可以進一步降低誤判的機率。
米勒-拉賓質數測試相對於費馬測試來說具有更高的成功率。實際上,選擇適當的隨機數可以使得它的誤判率非常低。通常情況下,增加測試次數

執行時間、問題大小等問題討論! 利用 MS Excel 畫出問題大小與執行時間的關係!

(1) Running Time

-21-
(2) Problem size n

i. 不適合大數字

ii. 執行時間隨著 𝑛 增加而線性增長,但因為對大數的隨機化處理,實際執行時間可能會稍有變化。

iii 同 ii

iv. 對於大範圍的質數生成,這種方法的效率較高

(3) 最大 Mersenne Prime Number

282589933−1

3. 心得

在實作 Primality Testing 的過程中,我對時間複雜度與實際執行時間之間的關係有了深刻的理解。雖然理論上可以透過時間複雜度來預測演算


法的效率,但實際執行時間往往受到硬體性能和編程語言的影響。在多次測試中,我發現即使是相同複雜度的演算法,執行時間可能有顯著差異,因此
在選擇演算法時,實際性能測試顯得尤為重要。這次經驗讓我明白,理解時間複雜度與實際執行時間的差異,不僅對演算法設計至關重要,也對未來的
學習與應用提共了寶貴的指導。

-22-
參考文獻
[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein, "Introduction
to Algorithms," Third Edition, The MIT Press, 2009.
[2] R.C.T. Lee, S.S. Tseng, R.C. Chang, and Y.T.Tsai, "Introduction to the Design and Analysis of
Algorithms," McGraw-Hill, 2005.
[3] Anany V. Levitin, "Introduction to the Design and Analysis of Algorithms," 3rd Edition,
Addison Wesley, 2012.
[4] Richard Neapolitan and Kumarss Naimipour, "Foundations of Algorithms," Fourth Edition,
Jones and Bartlett Publishers, 2010.
[5] https://www.hackerearth.com/practice/math/number-theory/primality-tests/tutorial/
[6] …

-23-

You might also like