> ## Content Index
> Fetch the complete content index at: https://www.geekjp.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 第3回　チキチキ　プログラミング初心者のための型に関する考察　～pythonで基数変換してみるよ～
- URL: https://www.geekjp.com/2019-11-12-235837/
- Published: 2019-11-12T14:58:37.000Z
- Updated: 2026-08-01T14:35:45.000Z
- Description: Pythonのbin関数だけでは表しにくい固定ビット幅や負数の2の補数を考えながら、10進数を2・8・16進数へ変換する関数を自作し、基数変換の仕組みをコードで確認します。
- Author: 工学じじい
- Tags: ゲームプログラミング, プログラミング, 技術, 情報処理技術者試験, Python, C言語, #Import 2026-07-19 20:21, #Import 2026-07-19 20:24

- 第3回 チキチキ プログラミング初心者のための型に関する考察 ～pythonで基数変換してみるよ～
  - はじめに
  - よろしい、ならば自作関数だ
    - 10進数と2進数を変換する関数を作る
    - pythonで表現してみる
  - 2，8，16進数のはなし
  - 10進数を2，8，16進数に変換する関数
  - そして負の数
    - (bin)だと２の補数に変換できないよねってこと
    - pythonで表現してみる
  - 所感

### はじめに

1回目で、型ってなんだ、2回目で整数型の中身と正負の整数のメモリ表現を見てみました。

[第1回 チキチキ プログラミング初心者のための型に関する考察](https://www.geekjp.com/2019-10-28-135618-2/)

[第2回 チキチキ プログラミング初心者のための型に関する考察](https://www.geekjp.com/2019-11-10-182219/)

2回目でも紹介した通り、pythonでは、組み込み関数binを使うことによって、整数を2進数に変換することができます。  
また、表示のみだけであればprint関数の書式設定で何とかなります。

[Gistのソースコードを直接開く](https://gist.github.com/gomta777/a9cf5f41f16806c69c15b764323f25f2?ref=geekjp.com)

ですが、

```
num = int(input())
print(bin(num))
print(bin(-num))

```

これで、入力を150とすると

```
150
0b10010110
-0b10010110

```

**0b**は2進数表記であることを表します。なので、**150**を表すビット列は**10010110**となります。pythonの型にはCやjavaの型（＝メモリサイズ＋表現形式の決まり）と違って決まったサイズがありませんので、150をそのまま2進数に変換した10010110が表示されています。  
これが例えば、CやJavaのshort型だったとすると

| 型     | メモリサイズ       |
| ----- | ------------ |
| short | 16ビット(2byte) |
| int   | 32ビット(4byte) |

なので、  
150(10進数) => 0000000011010110(2進数)  
となります。  
（pythonは、これが普通の世代から見るとなんか気持ち悪いｗ）

そして負の数のビット表現は2の補数を取って、

| 10進数  | 2進数              |
| ----- | ---------------- |
| 150   | 0000000011010110 |
| \-150 | 1111111100101010 |

となるはずですが、まさかの、-0b10010110となります。

### よろしい、ならば自作関数だ

#### 10進数と2進数を変換する関数を作る

引数に10進数と整数ｎ（2<=n<10)を与えると、それをｎ進数に変換して返す関数

def base\_conv(number, n):

を考えます。  
与えられたｎｕｍをｎ進数へ変換するには、前回説明した通り

[https://ko-gaku-jiji.hatenablog.jp/entry/2019/10/28/135618](https://www.geekjp.com/2019-10-28-135618/)

- num>0の間以下を繰り返す。
1. 与えられた整数numをnで割って、商q、余りrを記録
2. num=q

記録したrを逆順に並べるとn進数で表現されたnumとなります。

#### pythonで表現してみる

上の処理をpythonで書きます。

[Gistのソースコードを直接開く](https://gist.github.com/gomta777/944180fd85cc65ac5c810340ad8cd449?ref=geekjp.com)

ちゃんと動いてそうですね！  
実行結果もあってそうな気がします。

### 2，8，16進数のはなし

コンピュータの世界では、2の乗数と、それに関連して8の倍数を使うことが多いです。  
例えば、

8bit = 1byte  
1024(=2^10) bit = 1Mbit

0と1の2進数の世界でデータや命令ができているので自然といえば自然なことですね。  
また、2進数でデータを表記していると、どんどん長くなってしまいます。

0011101001010110(2進数）  
035126(8進数）  
3A56(16進数）

2進数だと16bit必要だったものが8進数だと7桁、16進数だと4桁で済んでしまいました。  
また、2進数、8進数、16進数は2の乗数が基数となっているため比較的簡単に相互変換可能です。なので、結構多くのプログラミング言語に2進数、8進数、16進数表記が使える機能が備わっています。

ちなみにｎ進数は０～（ｎー１）の数字を使って表すというルールがありました。（8進数なら０～７の数字で表される）  
16進数を考えてみるとちょっと面白いことになります。

![f:id:gomta777:20191112232742p:plain](https://www.geekjp.com/content/files/images/import/hatena/2019/11/20191112232742.png "f:id:gomta777:20191112232742p:plain")

図：16進変換

3797（10進数）を16で割っていって余りを下から並べると、

**１４ １３ ５**

となってしまします。１桁あたりに2つの数字が入ってしまいます。  
そりゃそうですよね。16進数なんで０～１５の数字を一けたに使うんだもん。でも、このままだと、繋げて書いたときに、14135と区別がつきません。困りました。  
っということで、16進数の１０～１５の数字が出てきてしまったときは、桁で使える数字（０～９）は売り切れてもうないのでアルファベットを使います。

| 10 | A |
| -- | - |
| 11 | B |
| 12 | C |
| 13 | D |
| 14 | E |
| 15 | F |

3797（10進数）=> 14 13 5(16進数）=> **ED5(16進数）**

### 10進数を2，8，16進数に変換する関数

10進数の数字と、基数（２，８，１６）を入力すると指定された基数に変換して返す関数を作ります。  
２，８，１６以外の基数が指定されたときは、Ｎｏｎｅを返します。

[Gistのソースコードを直接開く](https://gist.github.com/gomta777/fbbea79819417b53248b73f2e50f1119?ref=geekjp.com)

**print(base\_conv(3797, 16))**  
を試すと、ちゃんと  
**ED5(16)**  
が表示されます。

### そして負の数

#### (bin)だと２の補数に変換できないよねってこと

はじめに書いたとおり、組み込み関数bin()で整数をビット列に変換できます。しかしながら、負の数には対応しておらず、2の補数が表示されるわけではありません。これは、pythonが動的に型を扱う言語であることの特徴であって、別に欠点であるわけでも、バグでもありません。  
ただし、静的に型を扱う言語は多数あり、型についての知識も大事かなと思います。という理念のもとに、型についてグダグダと語ってきました（笑）  
話を戻して、2進数の負の数を2の補数で表示してみたい！という願望をかなえる関数を書いてみます。

型＝メモリサイズ＋表現方法

でしたね。ＪａｖａやＣ言語では、整数型はメモリサイズによってchar(byte)、short、int、longなどと名前が変わっていきます。

ちょっと中身で比べてみます。  
pythonで、  
**print(bin(3))**  
を実行すると  
**0b11**  
が表示されます。

しかし、例えばＣ言語では  
char c=3;  
とすると中身は  
00000011  
となります。  
short c=3;  
だと、  
0000000000000011  
です。  
charは8ビット、shortは16ビットの固定幅でデータが用意されるというわけです。

これを、Ｃ言語の場合で負の数（－３）にしてみます。  
char c=-3の場合：  
00000011 (元の2進数）  
11111100 (1の補数（ビット反転））  
11111101 (2の補数（1の補数＋１）） ← これがー3の8ビット表現

short c=-3野場合：  
0000000000000011 (元の2進数）  
1111111111111100 (1の補数（ビット反転））  
1111111111111101 (2の補数（1の補数＋１）） ← これがー3の8ビット表現

となります。pythonの場合は、ビット幅が決まっていないので内部表現はこうなっているとは限らないです。

#### pythonで表現してみる

今度は、この処理を、関数にしてみます。

[Gistのソースコードを直接開く](https://gist.github.com/gomta777/df7a4610df701f03939c32685210cd72?ref=geekjp.com)

def plus\_one(binarr):  
は、2進数で一番右のビットに1を足した結果を得る関数

def bit\_reverse(binarr):  
は、すべてのビットをビット反転する関数です。

結果も、ちゃんと動いているっぽいですね。

### 所感

pythonで基数変換する処理を書いてみました。  
たまには、こういうプログラムも楽しいかもしれない（笑）