我們可以用這樣的方式來表示一個十進制數:將每個阿拉伯數字乘以一個以該數字所處位置的(值減1)為指數,以10為底數的冪之和的形式。例如,123可表示為1*10^2+2*10^1+3*10^0這樣的形式。與之相似的,對二進制數來說,也可表示成每個二進制數碼乘以一個以該數字所處位置的(值-1)為指數,以2為底數的冪之和的形式。一般說來,任何一個正整數R或一個負整數-R都可以被選來作為一個數制系統的基數。如果是以R或-R為基數,則需要用到的數碼為0,1,....R-1。例如,當R=7時,所需用到的數碼是0,1,2, 3,4,5和6,這與其是R或-R無關。如果作為基數的數絕對值超過10,則為了表示這些數碼,通常使用英文字母來表示那些大於9的數碼。例如對16進制數來說,用A表示10,用B表示11,用C表示12,用D表示13,用E表示14,用F表示15。在負進制數中是用-R作為基數,例如-15(+進制)相當於110001(-2進制),並且它可以被表示為-2的冪級數的和數:
110001=1*(-2)^5+1*(-2)^4+0*(-2)^3+0*(-2)^2+0*(-2)^1+1*(-2)^0問題求解:設計一個程式,讀入一個十進制數的基數和一個負進制數的基數,並將此十進制數轉換為此負進制下的數:-R∈{-2,-3,-4,....-20}
輸入,輸出,樣例輸入,樣例輸出,代碼,PASCAL 代碼,C++ 代碼,
輸入
多組數據,每組數據每行有兩個數。第一個是十進制數N(-32768<=N<=32767); 第二個是負進制數的基數-R。
輸出
相對於輸入,應輸出此負進制數及其基數,若此基數超過10,則參照16進制的方式處理。
樣例輸入
30000 -2
-20000 -2
28800 -16
-25000 -16
樣例輸出
30000=11011010101110000(base-2)
-20000=1111011000100000(base-2)
28800=19180(base-16)
-25000=7FB8(base-16)
代碼
PASCAL 代碼
program bensen;const c:array[0..19] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J') ;var n,r,temp,o,i:longint; a:array[0..10000] of longint;begin readln(n,r); write(n,'='); repeat temp:=n mod r; n:=n div r; if temp<0 then begin temp:=temp-r; inc(n); end; inc(o); a[o]:=temp; until n=0; for i:=o downto 1 do write(c[a[i]]); writeln('(base',r,')');end.
解釋:
負數進制一樣。每次取的餘數保證在0~-m-1之間。(例如m=-16,則餘數應該在0~15)就可以直接輸出。 所以用系統的“mod”運算符的時候必須注意檢查是不是在該範圍(可能在m+1~0),否則就調整。調整的方法是:
if 餘數<0 then
begin
餘數=餘數-m;
商=商+1;
end;
C++ 代碼
#include <iostream>#include <string>using namespace std;const char nc[20] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};string ans;int main(){ int m, n, k, t, s; while(cin >> m >> n){ ans = ""; s = m; while(m != 0){ k = m % n; t = m / n; if(k < 0){ k -= n; t++; } m = t; ans.push_back(nc[k]); } cout << s << "="; for(int i = ans.length() - 1; i >= 0; i--){ cout << ans[i]; } cout << "(base" << n << ")" << endl; } return 0;}