2.4 進製轉換
日常生活中我們計數的方式有很多,如一年有12
個月,則是十二進位制,一周有七天,則是七進製,等等。平常我們用的最多的最習慣的十進位制,是古人留下來的財富。需要強調的是任何乙個值都可以用任何一種進製描述,但它的值是不變的,正如我們今天在一周中可以描述為星期幾,在乙個月中描述為多少號一樣。
使用r進製計數的規則:
只使用r
個基數:0,
1,2,···,
r-1;
逢r進一,退一當
r進行數的運算。
2.4.1 r進製數轉化為十進位制數
這個轉化問題較簡單,根據上面講的r
進製的計數規則進行展開就得到相應的十進位制數的表示方法。
(anan-1···a1a0.a-1a-2···a-m)r
=an*rn+an-1*rn-1+···
+a1*r1+a0*r0+a-2*r-2+···
+a-m*r-m
= ai*ri。
2.4.2 十進位制數轉化為
r進製數
由於十進位制數的整數與小數轉化為r
進製的方法不同,所以必須分開討論。先看十進位制整數的轉化,再討論十進位制小數的轉化,最後討論
r進製的計數及轉化問題。
1. 進製整數的轉化
通過具體例項進行分析,如對十進位制數325
轉化,根據原理可
按下式這樣假設:
(325
)10=3*102+2*101+5*100
=(anan-1…a1a0)r
=an*rn+an-1*rn-1+…
+a1*r1+a0*r0
=(an*rn-1+an-1*rn-2+…
+a1)*r+a0
兩邊同時除以r
,得到整數部分和整數部分相等,餘數和餘數相等,顯然右邊的餘數就是
a0,再進行同樣的處理就得到a1,一直這樣進行下去,直到左邊的數為0
時為止,由於先求出的是
r進製的最低位,再按求解過程倒過來寫出就得到相應的
r進製數。以r=
6為例,(
325)10=(1301
)6,轉化過程詳見圖2-1
所示。十進位制數轉化為r
進製數,得到整數部分的轉換規律就是「除
r取餘,反序輸出」。
2. 十進位制小數的轉化
通過具體例項進行分析,如對十進位制數0.325
轉化,根據原理
以這樣假設:
(0.375
)10=3*10-1+7*10-2+5*10-3
=(0.a-1a-2…a-m)r
=a-1*r-1+a-2*r-2+…
+a-m*r-m
=(a-1+a-2*r-1+…
+a-m*r-m+1)*r-1
兩邊同時乘以r
,等式兩邊的整數部分和小數部分分別相等,顯然右邊的整數部分就是
a-1,再去掉等式的整數部分,然後進行相同的處理,就求得了a-2,一直進行下去,直到左邊的值為0
時或到要求的精度為止,這樣就將十進位制小數轉化為相應的
r進製數了。以r=
2為例,(
0.375
)10=(0.011
)2,求解過程詳見圖2-2
所示,這樣就將十進位制小數轉化為相應的
r進製數,得到小數部分的轉換規律就是「乘
r取整,順序輸出」。
3.進製數轉化-
r進製數
大家對r
進製數都已經很熟悉了,但是,還有一種-
r進製數。任何乙個整數
n都可以表示成
n=,其中∈〔0,r-1
〕,是整數。並且》=0。
現在我們來討論r
進製數怎麼轉化為-
r進製數。需不需要先將
r進製數轉化為十進位制數,
再將相應的十進位制數利用上面的轉化歸律化為-r
進製數,當然這是一種方法,但我們完全可以不必這麼做。不妨以乙個具體例項來討論轉化規律,如:
=4*63+3*62+2*61+5*60。
將等式右邊改寫成乙個-6
進製數的形式:
4*(-
6)3+3*(-6
)2+2*(-6
)1+5*(-6)0。
比較觀察一下,發現偶次冪的項與6
進製數的相等,差別出在奇次冪的項,怎樣修改才使它滿足
-6進製數表示的形式呢?記住我們計算的原理:進製只是表示方式不同,值是不變的
那麼對於上面我們倒數第二項:2*61=x*(-6
)1,而基數x
是乙個0到5
之間的數,顯然是不能成立的,要相信,
x只能等於
-2,而
-2不能作為-
6進製數的基數,解決這個問題就向高位借乙個
1,這樣
x變為(
6.-2
),由於高位已經是相等的,所以高位的基數相應要加
1。若高位基數加
1後,值已超過
5,則修改冪。這樣就能確保值沒有變。
2.4.3 應用舉例
在資訊學奧賽中,巧妙地使用某些數制的特點,可能使解題變得相當簡單。請看下面幾道例題。
例15 火車轉軌問題。
圖2-3
中兩條軌道連線到乙個鐵路轉軌處,形成乙個鐵路轉軌網路的棧。其中右邊軌道為輸入端。如果執行了
push,push,pop,push,push,pop,pop,pop,
就會將輸入端的車皮編號順序
1,2,3,4
變成2,4,3,1
,請程式設計求左邊車皮編號為
1,2,3,4
時,在右邊軌道可能得到的所有車皮編號順序。
【演算法分析】
這個例子是典型的棧應用題。但如果單純使用棧技術,則在不斷的判定入棧出棧過程中,很容易迷失方向。現在讓我們仔細分析,看看有沒有其他方法可以解決此題:①四列車必須經過轉軌才能到達軌道的另一端,且進棧出棧各一次;②如果以1
代表進棧,
0代表出棧,則火車轉軌可以用一相二進位制數來表示,如,
10代表火車進棧後出棧,
01代表火車出棧後進棧;③四列火車都到達轉軌的另一側,一共進出棧八次,恰好乙個位元組
8個位;④由於必須先進棧才能出棧,故在二進位制的每一位數前,
1的個數總不少於
0的個數,否則轉軌內無車可出。這樣就巧妙地利用數的進製將原問題轉化為乙個求0至
255內的二進位制數中符合相應條件的數的個數。
【參考程式】
const n=4;
;var
a,b,c:array[1..n] of integer;
top,i:integer;
function judge(m:integer):boolean;
;var
s0,s1:integer;
i:integer;
begin
judge:=true;
s0:=0;
s1:=0;
for i:=1 to 2*n do
begin
if m mod 2 =0 then s0:=s0+1 else s1:=s1+1;
m:=m div 2;
if s0如果
0的個數比
1的個數少,則不滿足條件
}judge:=false;
exit;
end;
;end;;
if s0<>s1 then begin
;judge:=false;
exit;
end;
end;
procedure push;
var i:integer;
begin
b[top]:=a[1];
top:=top+1;
for i:=1 to n-1 do a[i]:=a[i+1];
a[n]:=0;
write(『push』);
end;;
procedure pop;
var i:integer;
begin
top:=top-1;
for i:=1 to n-1 do c[i]:=c[i+1];
c[n]:=b[top];
write(』pop』);
end;
procedure print(m:integer);
vart:array[1..2*n] of bollean;
i:integer;
begin
write(m,『 『);
for i:=1 to n do a[i]:=i;
for i:=1 to 2*n do
begin
t[i]:=(m mod 2=0);
m:=m div 2;
end;;
for i:=2*n downto 1do
if t[i] then pop else push;
for i:=i to do write(c[i]);
writeln;
end;
begin
top:=1;
for i:=1 to 255 do
if judge(i) then print(i);
writeln;
end.
進製轉換(任意進製轉換)
a進製轉b進製 思想 a進製轉十進位制 十進位制轉b進製 a進製轉十進位制 include include includeusing namespace std const int p 16 p代表 a進製 int main cout 十進位制轉b進製 include includeusing na...
進製進製進製 轉換
從剛學計算機就對進製轉換有著莫名的反感,2進製 8進製 10進製 16進製制各種轉換。下面就說下邏輯位址轉換成實體地址的求法吧 首先,使用者輸入乙個16進製制的數字cin hex logic add hex的意思是告訴計算機輸入的數是以16進製制方式輸入的 這個時候你要是輸出cout cout 經過...
進製轉換( R進製)
time limit 1 sec memory limit 128 mb 64bit io format lld submitted 3 accepted 1 submit status web board 我們可以用這樣的方式來表示乙個十進位制數 將每個阿拉伯數字乘以乙個以該數字所處位置的值 減1...