Pythonでは実行時にメモリ確保することでサイズを意識しないで整数を扱うことができる。
ただし、C言語と異なり負の値が2の補数形式で表現されないのでCの形式の二進数や十六進数を扱うのが少々面倒くさい。
本関数はC言語方式で表現された二進数の文字列を整数に変換する。
import re
def strbin2intdec(valstr: str, is_signed: bool, bits: int):
"""
2の補数形式で表現された数値を整数に変換する
Args:
valstr (str): 二進数表現された文字列
is_signed (bool): signedとして評価するならTrue
bits(int): 桁数
Returns:
int: 変換後の値(整数)
Raises:
TODO EXCEPTION: valstrから先頭の'0b'または末尾の'b'を消去して
残った文字列がbits個の0または1で構成されていない場合
Examples:
strbin2intdec('0b10001', True, 5) -> -15
Note:
PythonではC言語と異なり負の値が2の補数形式で表現されない
例) -10dは C言語では0b10110 だがPythonでは-0b1010となる
本関数はC言語方式で表現された二進数の文字列を整数に変換する
"""
# 先頭の'0b', 末尾の'b'をとる(いずれか一方)
if valstr.startswith('0b'):
valstr = valstr[2:]
elif valstr.endswith('b'):
valstr = valstr[:-1]
else:
pass # do nothing
# bitsと同じ数の0or1で構成されていない場合は例外を投げる
ptn = fr'[01]{{{bits}}}' # 5桁なら '[01]{5}' ※正規表現
if not re.fullmatch(ptn, valstr):
raise Exception
# 場合分けで処理
# ①signed かつ 先頭ビットが1のとき →桁数(bits)指定でbit反転して再反転
# ②signedで先頭bitが0のとき →そのままintに変換(2進数として解釈)
# ③unsignedのとき →そのままintに変換(2進数として解釈)
if is_signed and valstr[0] == '1':
mask_str = '1' * bits # 111...(bitsの数の1) ※桁数重要
mask_int = int(mask_str, base=2) # mask_strを2進数としてint変換
val_int = int(valstr, base=2)
ret = ~(mask_int ^ val_int) # 上記①の処理
else:
ret = int(valstr, base=2)
return ret