Documentation Python

Pythonのbin関数は、整数を2進数に変換するための組み込み関数です。ビット演算やフラグ管理など、低レベルなデータ処理で頻繁に使用されます。

基数変換関数の比較

関数変換先接頭辞使用例
bin()2進数0bbin(10)'0b1010'
oct()8進数0ooct(10)'0o12'
hex()16進数0xhex(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進数説明
00
11
210
3112¹ + 2⁰
4100
81000
16100002⁴
255111111112⁸ - 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進数表現

format関数でゼロパディング

# 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進数を扱うことができます。

参考文献

円