**Thuật toán nhân lũy thừa bằng bình phương** hoặc t**huật toán bình phương và nhân** là thuật toán tính nhanh lũy thừa tự nhiên của một số (thực hoặc nguyên), trong trường hợp cơ số là số nguyên có thể được rút gọn theo một môđun nào đó.

Phép nâng lên lũy thừa tự nhiên bậc *n* của số x (x được gọi là **cơ số**) được định nghĩa từ hệ thức

 {\displaystyle x^{n}={\begin{matrix}\underbrace {x\*x\*...\*x} \\n\end{matrix}}}

Với n lớn số phép nhân là rất lớn.

Ví dụ
-----

Chẳng hạn với n=35 quá trình tính {\displaystyle x^{35}} qua 35 bước:
{\displaystyle 1\Rightarrow x\Rightarrow x^{2}=x\*x\Rightarrow x^{3}=x^{2}\*x\Rightarrow ...\Rightarrow x^{35}=x^{34}\*x}  

Ta nhận xét rằng có thể giảm bớt số phép nhân chẳng hạn với dãy phép tính

{\displaystyle 1\Rightarrow x\Rightarrow x^{2}=x\*x},{\displaystyle \Rightarrow x^{4}=(x^{2})^{2}},{\displaystyle \Rightarrow x^{8}=(x^{4})^{2}}  

{\displaystyle \Rightarrow x^{16}=(x^{8})^{2}\Rightarrow x^{17}=x^{16}\*x},
{\displaystyle \Rightarrow x^{34}=(x^{17})^{2}\Rightarrow x^{35}=x^{34}\*x}.

Công thức đệ quy
----------------

Quá trình tính toán trên chính là quá trình tính nhờ công thức đệ quy

1. Với n=0 thì {\displaystyle x^{n}=1}
2. Với n>0 ta có công thức

{\displaystyle f(n)={\begin{cases}(x^{k})^{2},&{\mbox{khi }}n=2k\\(x^{k})^{2}\*x,&{\mbox{khi }}n=2k+1\end{cases}}}

Như vậy phép tính {\displaystyle x^{n}} được quy về một số phép bình phương và phép nhân do vậy mà có tên gọi **thuật toán bình phương và nhân**.

Giải thuật đệ quy
-----------------

Giải thuật sau tính đệ quy {\displaystyle x^{n}{\pmod {m}}}

````
**Function Square\_Multi** (int x, n, m){
**Var** Int Power
**If** n=0 **then return** 1
**Else** {
n:=LShift(n,1) 
Power:= Square_Multi (int x, n, m)
Power:=(Power^2) mod m
  **If** n **BitAnd** 1 =0 **then** 
 **Return** *Power*
  **Else** 
  **Return** (*Power\*x*) mod m 
} 
 }
````

Đoạn code viết bằng java:

````
public static int binhphuong (int x,int n,int m)
{
 int p;
 if (n==0) then return 1;
 p=binhphuong(x,n/2,m);
 if (n%2==0) 
return (p*p)%m;
 else
return (p*p*x)%m;
}
````

Chú ý rằng một số tự nhiên là chẵn hay lẻ chỉ phụ thuộc vào bít số 0 của nó nên trong giải thuật trên ta sử dụng toán tử AndBit để xác định tính chãn lẻ của n và sử dụng phép LShif để tính phần nguyên của n/2.

Giải thuật không đệ quy
-----------------------

Trong giải thuật đệ quy trên đây ta xét tính chẵn lẻ của n và liên tục chia n cho 2 lấy phần nguyên cho đến khi n=0. Thực chất quá trình này chính là tìm các bít của n. Do đó ta có thể thực hiện phép đổi ra số nhị phân trước sau đó tính lũy thừa theo quy tắc bình phương và nhân.

### Giải thuật

Đổi n ra số nhị phân ghi vào mảng {\displaystyle b[1..k]}

````
**Function Power\_Modulo**(*Int* x,n,m){  

 **Var** *Int* Power:=1
 **For** i=1 **to** k **do**
 Power:=(Power^2) *mod* m
 **If** b[i]=1 **then**
 Power:=(Power*x) mod m
 **Return** *Power* 
}
````

### Ví dụ

Trong ví dụ sau ta tính {\displaystyle {37}^{27}{\pmod {101}}}.

Đổi {\displaystyle n=27} ra số nhị phân ta được {\displaystyle 27=11011\_{(2)}}.

Bảng sau đây tính toán từng bước theo giá trị của các bít của {\displaystyle 27}.

Khởi tạo {\displaystyle p=1}.


|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| {\displaystyle b[i]} | {\displaystyle p=p^{2}} | {\displaystyle p=p{\pmod {101}}} | {\displaystyle p\*37} | {\displaystyle p={\pmod {101}}} |
| 1 | {\displaystyle 1^{2}=1} | 1 | {\displaystyle 1\*37=37} | {\displaystyle 37} |
| 1 | {\displaystyle 37^{2}=1369} | {\displaystyle 56} | {\displaystyle 56\*37=2072} | {\displaystyle 52} |
| {\displaystyle 0} | {\displaystyle 52^{2}=2704} | {\displaystyle 78} | - | {\displaystyle 78} |
| 1 | {\displaystyle 78^{2}=6084} | {\displaystyle 24} | {\displaystyle 24\*37=888} | {\displaystyle 80} |
| 1 | {\displaystyle 80^{2}=6400} | {\displaystyle 37} | {\displaystyle 37\*37=1369} | {\displaystyle 56} |

Như vậy ta có

 {\displaystyle {37}^{27}{\pmod {101}}=56}

Xem thêm
--------

* Toán học
* RSA (mã hóa)

Tham khảo
---------