Pythonのbin関数は、整数を2進数に変換するための組み込み関数です。ビット演算やフラグ管理など、低レベルなデータ処理で頻繁に使用されます。
基数変換関数の比較
| 関数 | 変換先 | 接頭辞 | 使用例 |
|---|
bin() | 2進数 | 0b | bin(10) → '0b1010' |
oct() | 8進数 | 0o | oct(10) → '0o12' |
hex() | 16進数 | 0x | hex(10) → '0xa' |
bin関数の基本
基本的な構文
bin(x)
x: 整数(int型)
- 戻り値:
'0b'で始まる2進数文字列
基本的な使用例
# 正の整数を2進数に変換
print(bin(0)) # 出力: 0b0
print(bin(1)) # 出力: 0b1
print(bin(10)) # 出力: 0b1010
print(bin(255)) # 出力: 0b11111111
# 負の整数を2進数に変換
print(bin(-1)) # 出力: -0b1
print(bin(-10)) # 出力: -0b1010
2進数の基本概念
10進数と2進数の対応
| 10進数 | 2進数 | 説明 |
|---|
| 0 | 0 | |
| 1 | 1 | |
| 2 | 10 | 2¹ |
| 3 | 11 | 2¹ + 2⁰ |
| 4 | 100 | 2² |
| 8 | 1000 | 2³ |
| 16 | 10000 | 2⁴ |
| 255 | 11111111 | 2⁸ - 1 |
2進数への変換アルゴリズム
def decimal_to_binary(n: int) -> str:
"""10進数を2進数に変換する手動実装"""
if n == 0:
return "0"
result = []
is_negative = n < 0
n = abs(n)
while n > 0:
result.append(str(n % 2)) # 余りを記録
n //= 2 # 2で割る
binary = ''.join(reversed(result))
return f"-{binary}" if is_negative else binary
# 使用例
print(decimal_to_binary(10)) # 出力: 1010
print(decimal_to_binary(255)) # 出力: 11111111
print(decimal_to_binary(-10)) # 出力: -1010
# bin関数と比較
print(bin(10)) # 出力: 0b1010(接頭辞付き)
2進数から整数への変換
int関数を使用
# 2進数文字列から整数に変換
binary_str = "0b1010"
decimal_value = int(binary_str, 2)
print(decimal_value) # 出力: 10
# 接頭辞なしでも変換可能
print(int("1010", 2)) # 出力: 10
print(int("11111111", 2)) # 出力: 255
# bin()とint()の往復変換
original = 42
binary = bin(original)
restored = int(binary, 2)
print(f"{original} → {binary} → {restored}")
# 出力: 42 → 0b101010 → 42
2進数リテラル
# 2進数リテラルで直接記述
a = 0b1010 # 10
b = 0b11111111 # 255
c = 0b1001_0110 # 150(アンダースコアで区切り可能)
print(a, b, c) # 出力: 10 255 150
# 計算も可能
result = 0b1010 + 0b0101
print(result) # 出力: 15
print(bin(result)) # 出力: 0b1111
フォーマット済み2進数表現
# 8ビット(1バイト)でゼロパディング
number = 5
print(format(number, '08b')) # 出力: 00000101
# 各種ビット幅での表現
for n in [1, 5, 10, 255]:
print(f"{n:3d} = {format(n, '08b')} (8bit)")
# 出力:
# 1 = 00000001 (8bit)
# 5 = 00000101 (8bit)
# 10 = 00001010 (8bit)
# 255 = 11111111 (8bit)
f文字列でのフォーマット
value = 42
# 各種フォーマット
print(f"10進数: {value}") # 10進数: 42
print(f"2進数: {value:b}") # 2進数: 101010
print(f"2進数: {value:#b}") # 2進数: 0b101010(接頭辞付き)
print(f"8bit: {value:08b}") # 8bit: 00101010
print(f"16bit: {value:016b}") # 16bit: 0000000000101010
接頭辞の削除
# bin()の結果から'0b'を除去する方法
number = 10
# 方法1: スライス
binary = bin(number)[2:]
print(binary) # 出力: 1010
# 方法2: format関数
binary = format(number, 'b')
print(binary) # 出力: 1010
# 方法3: f文字列
binary = f"{number:b}"
print(binary) # 出力: 1010
# 負の数の場合はスライスに注意
negative = -10
print(bin(negative)) # 出力: -0b1010
print(bin(negative)[3:]) # 出力: 1010(マイナス記号とobを除去)
print(format(negative, 'b')) # 出力: -1010
ビット演算との組み合わせ
基本的なビット演算
a = 0b1101 # 13
b = 0b1011 # 11
# AND: 両方のビットが1の場合のみ1
print(f"AND: {bin(a & b)}") # 出力: 0b1001 (9)
# OR: どちらかのビットが1なら1
print(f"OR: {bin(a | b)}") # 出力: 0b1111 (15)
# XOR: ビットが異なる場合に1
print(f"XOR: {bin(a ^ b)}") # 出力: 0b110 (6)
# NOT: ビットを反転(2の補数表現)
print(f"NOT: {bin(~a)}") # 出力: -0b1110 (-14)
ビットシフト演算
value = 0b0001 # 1
# 左シフト(2倍)
print(f"1 << 1 = {bin(value << 1)}") # 0b10 (2)
print(f"1 << 2 = {bin(value << 2)}") # 0b100 (4)
print(f"1 << 3 = {bin(value << 3)}") # 0b1000 (8)
# 右シフト(1/2)
value = 0b1000 # 8
print(f"8 >> 1 = {bin(value >> 1)}") # 0b100 (4)
print(f"8 >> 2 = {bin(value >> 2)}") # 0b10 (2)
print(f"8 >> 3 = {bin(value >> 3)}") # 0b1 (1)
実践的な使用例
ビットフラグの管理
# 権限フラグの定義
READ = 0b001 # 1
WRITE = 0b010 # 2
EXECUTE = 0b100 # 4
def show_permissions(flags: int) -> None:
"""権限フラグを表示"""
print(f"権限: {bin(flags)} ({flags})")
print(f" 読み取り: {'あり' if flags & READ else 'なし'}")
print(f" 書き込み: {'あり' if flags & WRITE else 'なし'}")
print(f" 実行: {'あり' if flags & EXECUTE else 'なし'}")
# 読み取りと実行権限を設定
user_permissions = READ | EXECUTE
show_permissions(user_permissions)
# 出力:
# 権限: 0b101 (5)
# 読み取り: あり
# 書き込み: なし
# 実行: あり
# 書き込み権限を追加
user_permissions |= WRITE
show_permissions(user_permissions)
# 実行権限を削除
user_permissions &= ~EXECUTE
show_permissions(user_permissions)
IPアドレスの2進数表現
def ip_to_binary(ip: str) -> str:
"""IPアドレスを2進数表現に変換"""
octets = ip.split('.')
binary_octets = [format(int(octet), '08b') for octet in octets]
return '.'.join(binary_octets)
def binary_to_ip(binary: str) -> str:
"""2進数表現をIPアドレスに変換"""
binary_octets = binary.split('.')
decimal_octets = [str(int(octet, 2)) for octet in binary_octets]
return '.'.join(decimal_octets)
# 使用例
ip = "192.168.1.1"
binary_ip = ip_to_binary(ip)
print(f"IP: {ip}")
print(f"Binary: {binary_ip}")
# 出力:
# IP: 192.168.1.1
# Binary: 11000000.10101000.00000001.00000001
# 逆変換
restored_ip = binary_to_ip(binary_ip)
print(f"Restored: {restored_ip}") # 192.168.1.1
ビット数のカウント
def count_bits(n: int) -> dict:
"""整数のビット情報を取得"""
binary = bin(abs(n))[2:]
return {
"value": n,
"binary": bin(n),
"bit_length": n.bit_length(),
"ones": binary.count('1'),
"zeros": binary.count('0')
}
# 使用例
for value in [0, 1, 7, 8, 255, 256]:
info = count_bits(value)
print(f"{info['value']:3d}: {info['binary']:>12s}, "
f"長さ={info['bit_length']}, 1の数={info['ones']}")
# 出力:
# 0: 0b0, 長さ=0, 1の数=0
# 1: 0b1, 長さ=1, 1の数=1
# 7: 0b111, 長さ=3, 1の数=3
# 8: 0b1000, 長さ=4, 1の数=1
# 255: 0b11111111, 長さ=8, 1の数=8
# 256: 0b100000000, 長さ=9, 1の数=1
カラーコードの操作
def color_to_rgb(color: int) -> tuple:
"""16進数カラーコードをRGB値に分解"""
r = (color >> 16) & 0xFF
g = (color >> 8) & 0xFF
b = color & 0xFF
return r, g, b
def rgb_to_color(r: int, g: int, b: int) -> int:
"""RGB値を16進数カラーコードに結合"""
return (r << 16) | (g << 8) | b
# 使用例
color = 0xFF5733 # オレンジ色
# RGBに分解
r, g, b = color_to_rgb(color)
print(f"Color: #{color:06X}")
print(f"R: {r:3d} ({bin(r):>10s})")
print(f"G: {g:3d} ({bin(g):>10s})")
print(f"B: {b:3d} ({bin(b):>10s})")
# 出力:
# Color: #FF5733
# R: 255 (0b11111111)
# G: 87 ( 0b1010111)
# B: 51 ( 0b110011)
# RGBからカラーコードに戻す
restored = rgb_to_color(r, g, b)
print(f"Restored: #{restored:06X}") # #FF5733
注意点
戻り値は文字列
binary = bin(10)
print(type(binary)) # <class 'str'>
# 計算には使えない
# print(binary + bin(5)) # 文字列連結になる: 0b10100b101
# 整数に戻して計算
result = int(bin(10), 2) + int(bin(5), 2)
print(bin(result)) # 0b1111 (15)
負の数の表現
# Pythonの負の数は符号付き表現
print(bin(-1)) # -0b1
print(bin(-10)) # -0b1010
# 2の補数表現を取得する場合
def twos_complement(n: int, bits: int = 8) -> str:
"""2の補数表現を取得"""
if n >= 0:
return format(n, f'0{bits}b')
else:
return format((1 << bits) + n, f'0{bits}b')
# 使用例
print(twos_complement(-1, 8)) # 出力: 11111111
print(twos_complement(-10, 8)) # 出力: 11110110
まとめ
| 操作 | 方法 | 例 |
|---|
| 整数→2進数 | bin(n) | bin(10) → '0b1010' |
| 2進数→整数 | int(s, 2) | int('1010', 2) → 10 |
| ゼロパディング | format(n, '08b') | format(5, '08b') → '00000101' |
| 接頭辞なし | f"{n:b}" | f"{10:b}" → '1010' |
| ビット長取得 | n.bit_length() | (255).bit_length() → 8 |
bin関数は、ビット演算、フラグ管理、ネットワークプログラミングなど、低レベルなデータ処理で重要な役割を果たします。format関数やint関数と組み合わせることで、柔軟に2進数を扱うことができます。
参考文献