🐈
pythonの bin()関数の中身を見る
二進数文字列に変換してくれる関数 bin()
※0b
がつくことに注意
a = 5
b = bin(a)
print(b)
#--- output ---
# 0b101
今週プログラミングで使う機会があったので、こういう組み込み関数のソースでも見てみる。
結論としては思っていた何倍も長く、なるほどね、とはならなかった。
エントリーポイントがあっているのか怪しいですが、おそらくこちら
cpython/Python/bltinmodule.c
static PyObject *
builtin_bin(PyObject *module, PyObject *number)
/*[clinic end generated code: output=b6fc4ad5e649f4f7 input=53f8a0264bacaf90]*/
{
return PyNumber_ToBase(number, 2);
}
PyNumber_ToBase が下に続く。2しか使っていませんでしたが、2 or 8 or 10 or 16のassertがあるんですね。
cpython/Objects/abstract.c
PyNumber_ToBase(PyObject *n, int base)
{
if (!(base == 2 || base == 8 || base == 10 || base == 16)) {
PyErr_SetString(PyExc_SystemError,
"PyNumber_ToBase: base must be 2, 8, 10 or 16");
return NULL;
}
PyObject *index = _PyNumber_Index(n);
if (!index)
return NULL;
PyObject *res = _PyLong_Format(index, base);
Py_DECREF(index);
return res;
}
一応_PyLong_Format
も見てみます
cpython/Objects/longobject.c
PyObject *
_PyLong_Format(PyObject *obj, int base)
{
PyObject *str;
int err;
if (base == 10)
err = long_to_decimal_string_internal(obj, &str, NULL, NULL, NULL);
else
err = long_format_binary(obj, base, 1, &str, NULL, NULL, NULL);
if (err == -1)
return NULL;
return str;
}
同一ファイルのlong_format_binary
がある。長いので転記はやめておきます。
writerがNULLなのでv = PyUnicode_New(sz, 'x')
が仕事をしているように読めました。
出力の先頭の0b
もここで見て取れました。(0x[16進数], 0o[8進数])もあるみたいですね。
今後の課題として読めるよう頑張ります。
Discussion