このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

  • 追加された行はこの色です。
  • 削除された行はこの色です。
*目次 [#j041f5e9]

#contents


*10進数を2進数に変換する [#t22ee616]
*基数変換 [#lef36e97]

 まず偶数なら、2進数の一番下の桁が0になる。また、奇数なら1になる。これは2で割った余りなので当然である。次の桁を求めるには、その桁が一番下の桁になるようにすればよいのだから、元の数を2で割る。整数で計算するので、小数点以下は切り捨てる。その結果が奇数なら1、偶数なら0になる。割った結果が0になるまで、次々に2で割って奇数か偶数かで1か0を左(一番上の桁)から加えていく。
 ''基数''とは文字通り基本となる数、基礎となる数のことである。例えば、2進数の基数は2、10進数の基数は10である。いくつで桁が上がるかということが、基数で決定される。

 ''基数変換''とは基数を変換することである。数そのものの大きさは変化せずに、表記が変わる。どの進数で表現しても数値の大きさ自体は変わらない。2進数であれば機械にとって便利で、10進数や16進数であれば人間にとって便利になるわけである。つまり、その数を扱いたいモノ(機械や人間)のために、基数変換が行われる。

#img(http://security2600.sakura.ne.jp/main2/image3/kisuu_henkan.jpg)
#img(,clear)


**整数部 [#m8035a5a]

 整数部と小数部で変換方法が違うので注意が必要。

***2進数→10進数 [#i868c7e3]

 2進数の各桁に2SUP{n};の重み付けを行えばよい。

例:(101011.1101)SUB{2};を10真数に変換する。

+整数部は下位の桁から順に2の0乗、1乗、2乗、…の重み付け(乗算)を行い、小数部は上位の桁から順に2の-1乗、-2乗、…の重み付けを行う。
+重み付けをした結果を加算する。
--&mimetex("(101011.1101)_{2}=1 \times 2^5 + 0 \times 2^4 + 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 + 1 \times 2^{-1} + 1 \times 2^{-2} + 0 \times 2^{-3} + 1 \times 2^{-4}=(43.8125)_{10}");
+よって、(101011.1101)SUB{2};=(43.8125)SUB{10};


***10進数→2進数 [#v2d5df7d]

例:10進数43を2進数に変換する。

+(43)SUB{10};を変換後の基数2で割り、商と余りを求める。
+ステップ1の商を基数2でさらに割り、商と余りを求める。これを商が0になるまで繰り返す。
+除算の余りを計算とは逆の順番に並べる。
--43÷2=21 余り1
--21÷2=10 余り1
--10÷2=5 余り0
--5÷2=2 余り1
--2÷2=1 余り0
--1÷2=0 余り1
+よって、(43)SUB{10};=(101011)SUB{2};


***2進数→8進数 [#z471f126]

 2進数の3桁は、8進数の1桁に対応していることが次の図からわかる。

|''2進数''|''8進数''|
|000|0|
|001|1|
|010|2|
|011|3|
|100|4|
|101|5|
|110|6|
|111|7|
|1000|10|

例:(11010111)SUB{2};を8進数で表してみる。

+まず右から3ビットずつ区切る。
--「11」「010」「111」になる。「11」は2ビットだが、「011」だと考えてよい。
+それぞれを10進数に直す。
--「3」「2」「7」になる。
+それらをすべて並べれば、8進数「327」が得られる。



***8進数→2進数 [#n0f504b9]

 8進数の各桁の値を3ビットの2進数にして繋げばよい。

例:8進数の「75」を2進数で表す。

+8進数の「75」を各桁で2進数に直す。
--(7)SUB{8};=(111)SUB{2};、(5)SUB{8};=(101)SUB{2};
--2進数に変換して3桁に足りないときは、頭に0を追加して3桁に直しておく。
+「111」「101」を繋ぐと、「111101」になる。


***2進数→16進数 [#e10a4419]

 4桁に区切って、2進数の重みを掛けた数を足す。

例:

-「1111 1111」=「FF」
--「1111 1111」を4桁に区切る。まず、前半の「1111」だけを考える。
--&mimetex("1 \times 2^3 + 1 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 = 15_{\( 10 \) = F_{\( 16 \)}");
--よって、これが2つあるので、FFである。


***16進数→2進数 [#lf8515d4]

 16進数の各桁の値を4ビットの2進数にして繋げばよい。

例:16進数の「F7」を2進数で表す。
--(F)SUB{16};=(1111)SUB{2};、(7)SUB{16};=(111)SUB{2};
---(111)SUB{2};は4桁にするために、頭に0を追加して(0111)SUB{2};にしておく。
+「1111」「0111」を繋ぐと、「11110111」になる。



**小数部 [#y0fbc695]

***10進小数→2進小数 [#yf5c6281]

 整数部分と小数部分に分けて、整数部分は2で割っていき、小数部分は2を掛けていく。ここでは小数部分を解説する。

例1:10進小数0.8125を2進数に変換する。

+(0.8125)SUB{10};に変換後の基数2を掛ける。
+ステップ1の乗算結果の小数部に基数2をさらに掛ける。これを小数部が0になるまで繰り返す。
+乗算の結果、求められた整数部の値を計算した順に並べる。
--0.8125×2=1.625
--0.625×2=1.25
--0.25×2=0.5
--0.5×2=1.0
+よって、(0.8125)SUB{10};=(0.1101)SUB{2};

例2:10進小数7.625を2進数に変換する。

+整数部と小数部に分ける。
+整数部(7)SUB{10};を2進数で表示すると(111)SUB{2};になる。
+小数部(0.625)SUB{10};を2進数に変換するには次の通りに計算する。
--小数部の「0.625」を2倍していく。
+++「0.625×2=1.25」だから、2進小数の小数第1位は1(計算の1桁目に注意)。
+++「0.25×2=0.5」(1.25から1を引いておく)だから、2進小数の小数第2位は0。
+++「0.5×2=1.0」だから、2進小数の小数第3位は1。
--2進数の小数部は(101)SUB{2};となる。
+よって、(7.625)SUB{10};=(111.101)SUB{2};


***10進小数→n進小数 [#a0aa69f2]

 整数部分と小数部分に分けて、整数部分はnで割っていき、小数部分はnを掛けていく。基本的には「10進数→2進小数」と方法は同じ。


**分数 [#w6ba42d5]

***n進分数→10進分数 [#s04bc8a5]



*基数変換のアルゴリズム [#t22ee616]

**10進数を2進数に変換するアルゴリズム [#w0fb9a6a]

 まず偶数なら、2進数の一番下の桁が0になる。また、奇数なら1になる。これは2で割った余りなので当然である。次の桁を求めるには、その桁が一番下の桁になるようにすればよいのだから、元の数を2で割る。整数で計算するので、小数点以下は切り捨てる。その結果が奇数なら1、偶数なら0になる。割った結果が0になるまで、次々に2で割って奇数か偶数かで1か0を左(一番上の桁)から加えていく。

 10進数を2進数に変換するアルゴリズムは次の通りである。

-Input:A(10進数の整数)
-Output:B(Aを2進数に変換した結果)

#code(){{
while A≧1 do
	rem←A%2
	if rem==1 then
		Bの一番上の桁に1を追加
	else
		Bの一番上の桁に0を追加
	A←A/2
return B

}}

***Javaによる実装 [#z291b19c]

#code(java){{
/*
 * 入力:10進数
 * 出力:変換した2進数
 */
public class Dec2Bin {

	public static void main(String[] args) {
		int dec = 0;		//10進数
		String numstr = "";	//変換後の文字列
		
		//第1引数に10進数を指定する
		if(args.length != 1){
			System.out.println("10進数を2進数に変換します。");
			System.out.println("書式:Dec2Bin <10進数の値>");
			return;
		}
		try{
			dec = Integer.parseInt(args[0]);
		}catch(NumberFormatException e){
			System.out.println("10進数を入力してください。");
			return;
		}
		
		int d=dec;
		
		//10進数が1以上である間繰り返す
		while(d>1){
			//1番下の桁を求める
			int rem = d%2;	//2で割った余りを求める
			
			//その数字を一番上の桁に追加する
			if(rem == 1){
				numstr = "1" + numstr;
			}else{
				numstr = "0" + numstr;
			}
			
			//次の桁の計算のために基数(=2)で割る
			d = d/2;
			
			//現在の値を表示する
			System.out.println("rem=" + rem + "\td=" + d + "\tnumstr=" + numstr);
		}
		System.out.println("10進数" + dec + "は2進数で" + numstr + "である。");
	}
}

}}

例:165という10進数を上記のプログラムの第1引数に指定して実行した結果

 rem=1	d=82	numstr=1
 rem=0	d=41	numstr=01
 rem=1	d=20	numstr=101
 rem=0	d=10	numstr=0101
 rem=0	d=5	numstr=00101
 rem=1	d=2	numstr=100101
 rem=0	d=1	numstr=0100101
 10進数165は2進数で0100101である。

**10進数をn進数に変換するアルゴリズム [#d5d30a9f]

 10進数をn進数に変換するアルゴリズムは次の通りである。

-Input:A(10進数の整数),N(基数。ただし、1≦N≦16の整数)
-Output:B(Aを2進数に変換した結果)

#code(){{
while A≧1 do
	rem←A%N
	if rem==0 then
		Bの一番上の桁に0を追加
	else if rem==1 then
		Bの一番上の桁に1を追加
	else if rem==2 then
		Bの一番上の桁に2を追加
	else if rem==3 then
		Bの一番上の桁に3を追加
	else if rem==4 then
		Bの一番上の桁に4を追加
	else if rem==5 then
		Bの一番上の桁に5を追加
	else if rem==6 then
		Bの一番上の桁に6を追加
	else if rem==7 then
		Bの一番上の桁に7を追加
	else if rem==8 then
		Bの一番上の桁に8を追加
	else if rem==9 then
		Bの一番上の桁に9を追加
	else if rem==10 then
		Bの一番上の桁にAを追加
	else if rem==11 then
		Bの一番上の桁にBを追加
	else if rem==12 then
		Bの一番上の桁にCを追加
	else if rem==13 then
		Bの一番上の桁にDを追加
	else if rem==14 then
		Bの一番上の桁にEを追加
	else
		Bの一番上の桁にFを追加
	A←A/N
return B

}}

 if文とelse if文の条件は余り(rem)を0からチェックしていった方が、トータルのチェック数が少ない。Nの基数に10を入力したときには、rem==10以降をなるべくチェックしないほうが効率よいからである。

 アルゴリズム自体は上記で問題ないが、if文とelse if文が少しエレガントでない。プログラムにするときには、switch文を使って書いた方がすっきりする。

*2進数を10進数に変換する [#d875173d]

**2進数を10進数に変換するアルゴリズム [#e4d2ff9b]

 2進数の文字列を左から処理する方法と、右から処理する方法が考えられる。ここでは左(一番上の桁)から計算していく方法を解説する。求める10進数を0にしておき、その桁の数を足す。次の桁に行く前に、一桁上がるので2倍する。

 2進数を10進数に変換するアルゴリズムは次の通りである。

-Input:A(2進数の整数)
-Output:B(Aを10進数に変換した結果)

#code(){{
for i=0,…,length(A) do
	B←B*2
	if (Aの上からi番目の数値)==1 then
		B←B+1;
return B

}}

***Javaによる実装 [#s62af86b]

#code(java){{
/*
 * 入力:2進数
 * 出力:変換した10進数
 */
public class Bin2Dec {

	public static void main(String[] args) {
		int dec=0;	//10進数
		
		//コマンドラインから入力した2進数を取得する
		if(args.length != 1){
			System.out.println("2進数を10進数に変換します。");
			System.out.println("書式:Bin2Dec <2進数の値>");
			return;
		}
		String numstr=args[0];
		
		//文字列の最後まで繰り返す
		for(int i=0;i<numstr.length();i++){
			dec=dec*2;
			
			//その位置の文字が1なら、10進数に1を足す
			if(numstr.charAt(i) == '1'){
				dec+=1;
			}else if(numstr.charAt(i) != '0'){
				//1と0以外ならエラー
				System.out.println("2進数ではありません。");
				return;
			}
			
			//途中結果を表示する
			System.out.println(i + "番目の数字:" + numstr.charAt(i) + "\t dec=" + dec);
		}
		
		//結果を表示する
		System.out.println("2進数" + numstr + "は10進数で" + dec + "です。");
	}
}

}}


*演習問題 [#xac525e5]

-問:次の10進小数のうち、8進数に変換したときに有限小数になるものはどれか?
--ア:0.3、イ:0.4、ウ:0.5、エ:0.8
---答え:ウ


*参考文献 [#ta9822aa]

-『Eclipseによる体験学習 Javaではじめるアルゴリズム入門』
-『ソフトウェア開発技術者 合格エッセンシャルハンドブック』
-『ソフトウェア開発技術者 午前対策(基礎編) テキスト』
-『情報処理技術者試験 SUPER記憶術SERIES まんがでわかる情報処理の基本 デジタル数学編』