Chuyển đổi cơ số
Đoàn Phương Nam
Chúng ta đã có dịp làm quenvới xử lý số lớn ở các tập báo trước. Trong bài báo này tôi xin
được trao đổithêm với bạn đọc chủ đề trên thông qua bài toán chuyển đổi một số từ cơ số
nàysang cơ số khác. Đây là một bài toán khá quan trọng và đầy lý thú. Đối với conngười
thì cơ số thập phân (cơ số 10) là rất quen thuộc, chúng ta thường thaotác, tính toán trên hệ
cơ số 10. Nhưng đối với máy tính thì khác, cơ số 10không phải là?sở trường? mà lại làcơ
số nhị phân (tức cơ số 2). Chính vì vậy bất kì ai học Tin học đều phải hiểucơ số, biết cách
chuyển một số từ cơ số này sang cơ số khác.
Giới thiệu qua về cơ số
Trong hệ thống thập phân mộtsố có thể được phân tích bằng tổng của luỹ thừa 10. Như
vậy: 2808
10
= 2*10
3
+ 8*10
2
+ 0*10
1
+ 8*10
0
Cũng vậy, trong hệ cơ số kmột số M ở hệ cơ số k có thể phân tích bằng tổng luỹ thừa k. Ví
dụ với k = 28thì 289
28
= 2*28
2
+ 8*28
1
+ 9*28
0
Bài toán chuyển đổi cơ số S sang cơ số D
N-2
+..+ w
N
*S
0
= (..((w
1
*S+w
2
)*S+w
3
)..)*S+w
N
. Tatính
theo độ ưu tiên trong ngoặc (vì tính như thế sẽ mất ít phép tính toánnhất). Vì W có thể rất
lớn, như vậy từng giá trị trong ngoặc cũng có thể rấtlớn, ta không thể dùng các kiểu số có
sẵn để lưu trữ mà phải dùng xâu để lưu.Để tính giá trị biểu thức trên ta phải thao tác hai
loại phép toán đó là : nhânmột số lớn với S (S<=35) và cộng một số lớn với một số <=35.
- Để chuyển một số từ cơ sốthập phân sang cơ số D, ta chia số đó cho D phần dư sẽ là ký
tự cuối cùng củabiểu diễn đó. Sau đó ta lại lấy thương của phép chia vừa rồi chia tiếp cho
D,phần dư nhận được sẽ là ký tự đứng sát trước của ký tự cuối cùng. Cứ làm nhưvậy cho
đến khi thương bằng không. Như vậy để chuyển một số từ cơ số thập phânsang cơ số D ta
phải có thao tác phép toán là: chia một số lớn cho số D(D<=35) và lấy dư.
Trong bài viết 'Lập trình với các số Khổng lồ? củatác giả Lê Mạnh Dũng ở số 8 năm 2001,
tác giả đã đề cập tới việc tính toán vớicác số lớn. Song nếu áp dụng thuật toán đó để giải
bài này thì e rằng làm phứctạp bài toán và mất nhiều thời gian cài đặt cũng như thời gian
chạy. Vì thuậttoán mà tác giả Lê Mạnh Dũng đã đề cập là thuật toán xử lý hai số lớn còn
cácphép toán cần trong chương trình này là xử lý một số lớn với một số nhỏ.
Thuật toán cộng một số lớn với một số nhỏ
function cong(x:string;num:longint): string;
nho:=tich div 10;
kq:=char(tich mod 10+48)+kq;
end;
while nho>0 do
begin
kq:=char(nho mod 10+48)+kq;
nho:=nho div 10;
end;
nhan:=kq;
end;
Thuậttoán nhân trình bày ở trên?y trang?thuật toán nhân với số có một chữ số. Ta không
cần quan tâm nó có bao nhiêu chữsố cứ coi nó chỉ là số có một chữ số. Song cũng giống
như thuật toán cộng nhớcó thể lớn. Không đơn thuần nhớ chỉ là số có một chữ số. Chính
điều này làm takhó nhận ra thuật toán trên.
Thuật toán chia một số lớn cho một số nhỏ
functionchiăx:string;num:longint;var du:integer):string;
var nho,k :longint;
kq:string;
begin
nho:=0; kq:='';
for k:=1 to length(x) do
begin
nho:=nho*10+ord(x[k])-48;
kq:=kq+char(nho div num+48);
nho:=nho mod num;
end;
du:=nho;
while (length(kq)>0)and(kq[1]='0') do delete(kq,1,1);
chia:=kq;
end;