BD HSG: Tính toán với các số lớn

Chia sẻ bởi Phạm Khắc Tuấn | Ngày 26/04/2019 | 40

Chia sẻ tài liệu: BD HSG: Tính toán với các số lớn thuộc Tin học 12

Nội dung tài liệu:

Vấn đề tính toán với các số lớn
Phạm Khắc Tuấn
Tổ Toán Tin
Vấn đề tính toán với các số lớn có ý nghĩa rất lớn trong thực tế. Chẳng hạn, thuật toán mã hoá công khai RSA (do Rivers, Shamir và Adleman viết ra vào năm 1978) sử dụng tới 512 số khoá (thuật toán này có liên quan đến việc phân tích các số nguyên tố). Trong nhiều ngành khoa học kỹ thuật khác, chúng ta còn phải sử dụng tới các con số lớn hơn thế rất nhiều. Trong bài báo này, chúng tôi muốn trình bày với đọc giả đôi nét xung quanh vấn đề tính toán với số lớn qua các phép toán phổ biến như: cộng, trừ, nhân, chia, khai căn, luỹ thừa và kiểm tra tính nguyên tố.
Trước hết chúng ta cùng bàn về một số môi trường lập trình để thể hiện chương trình tính toán với số lớn:
Với ngôn ngữ lập trình Pascal: Nếu sử dụng cấu trúc dữ liệu (CTDL) kiểu chuỗi thì chỉ có thể thao tác với các số trong phạm vi 255 chữ số; nếu sử dụng CTDL kiểu mảng thì có thể thao tác với các số lớn vượt xa giới hạn 255 chữ số gấp nhiều lần, có thể đạt tới hàng ngàn chữ số (lưu ý khi làm việc với CTDL mảng là kích thước của mảng cho phép khai báo một số rất lớn nhưng vẫn bị hạn chế vì bộ nhớ dành cho mảng là 64K); cách làm khác là sử dụng con trỏ để khai thác vùng nhớ Heap của máy tính, bằng cách sử dụng CTDL kiểu mảng động để thao tác với các số lớn tới hàng tỉ con số (vì kích thước mảng động phụ thuộc vào dung lượng Ram thực tế của máy tính).
Với ngôn ngữ lập trình Delphi hay Java ta có thể thao tác với các số lớn tới hàng tỉ con số thông qua CTDL kiểu chuỗi hay CTDL kiểu mảng.
Ngoài ra, cũng có thể sử dụng các ngôn ngữ thông dụng khác như C/C++ để viết chương trình. Chúng ta tạm thời thoả thuận với nhau rằng: tuỳ thuộc yêu cầu mà lựa chọn môi trường lập trình cũng như CTDL phù hợp. Vấn đề quan trọng là thuật toán thể hiện, phần tiếp theo sẽ trình bày các thuật toán có liên quan.
1.Cộng hai số:
Để cộng hai số nguyên a và b ta thực hiện như phép cộng bằng tay hai số thông thường. Tức là thực hiện lần lượt phép tính từ bên phải, sử dụng một biến trung gian để lưu phần dư tại mỗi bước.
2.Trừ hai số:
Giả sử cần tìm c = a - b ( a=a1a2..an; b=b1b2..bm; n? m), thuật toán được mô tả qua đoạn chương trình sau:
du:=0;
for i:= n downto n-m +1 do
begin
tg:=ai -bi - du;
if (tg < 0) then
begin
du:=1;tg:=tg+10;
end;
else du:=0;
ci:=tg;
end;
for i:= n-m to 1 do{chuyển đoạn đầu còn lại (nếu có) của a vào c}
begin
ci:= (ai+du ) mod 10;
du:=(a+du) div 10;
end;
if (du>0) then c0:= du;
3.Nhân hai số:
Thuật toán này có thể dễ dàng suy ra từ thuật toán cộng hai số, xin dành cho bạn đọc tự tìm hiểu.
4.Chia hai số:
- Cắt lần lượt từng "đoạn" của số bị chia tính từ bên trái (có cộng thêm phần dư của các bước trung gian).
- Đem chia các đoạn đó cho số chia bằng phép toán trừ.
- Thương tìm được chính là dãy các số là kết quả của phép chia các "đoạn" cho số chia (được phát triển dần về phía bên phải).
- Phần dư của phép chia chính là "đoạn" còn lại không thể chia được nữa.
5.Khai căn bậc hai của một số nguyên X (kết quả là một số nguyên):
b:=1;
l:=;
{chia số X thành tập các số ai có hai chữ số tính từ trái, riêng số a1 có thể có một hoặc hai chữ số tuỳ theo l chãn hay lẻ }
If ( l div 2 =1) then
Begin j:=1;
Y[j]:=X[1]; i:=2;
End Else
Begin i:=1;j:=0; end;
While (iBegin
j:=j+1;
Y[j]:=X[i]*10+X[i+1];
i:=i+2;
end;
{ khởi tạo giá trị ban đầu}
a:=round(sqrt(Y[1]));s1:=Y[1
* Một số tài liệu cũ có thể bị lỗi font khi hiển thị do dùng bộ mã không phải Unikey ...

Người chia sẻ: Phạm Khắc Tuấn
Dung lượng: | Lượt tài: 1
Loại file:
Nguồn : Chưa rõ
(Tài liệu chưa được thẩm định)