前提・実現したいこと
pythonでの符号付き8ビットの変換をしたい
該当のソースコード
python
1a = 0b11110011 2print(a)#243と表示されるのを-13と表示したい 3 4x = 0b01110011 5print(-0b10000000|x)#これが正解のよう 6print(0b10000000|-x) 7print(-(0b10000000|x))
試したこと
前提・実現したいこと
pythonでの符号付き8ビットの変換をしたい
該当のソースコード
a = 0b11110011
から下位7ビット分を抜き出したものをxとする。
x = 0b1110011
-0b10000000|x
を実行すると、負の値が表示されました。
ただ、どうしてこのようになるのかが良くわかりません。
なぜ
・print(-0b10000000|x) #-13
・print(0b10000000|-x) #-115
とで出てくる値が異なるのでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
前提
pythonの整数型と数値リテラルの話
pythonの数値型はint
, float
, complex
の3種類です。
https://docs.python.org/ja/3/library/stdtypes.html#numeric-types-int-float-complex
これに定数値を代入するのに数値リテラルが使用されます。
https://docs.python.org/ja/3.10/reference/lexical_analysis.html#numeric-literals
整数を表す数値リテラルは10進数整数値、2進数整数値、8進数整数値、16進数整数値から選べますが、何を使ったとしても型としてはint
になります。
例えば、
- 10進数整数値の
256
- 2進数整数値の
0b100000000
- 8進数整数値の
0o400
- 16進数整数値の
0x100
は全て同じint型の値になります。
符号はリテラルの一部ではないのですが、符号もつけると
- 10進数整数値の
-256
- 2進数整数値の
-0b100000000
- 8進数整数値の
-0o400
- 16進数整数値の
-0x100
も同じく、全て同じint
型の値になります。
pythonのint
型の桁数の話
そしてpythonの整数型int
は桁数に制限がありません。
なので、「符号付き8ビットの変換」という表現は適切ではなく、2の補数表現
https://ja.wikipedia.org/wiki/2%E3%81%AE%E8%A3%9C%E6%95%B0
で8桁の数値にするならどうするか?と考えるべきです。
負数を2の補数で表現する話
任意の整数x
をbits
ビットの2の補数で表現される正数に変換するコードは↓な感じになります。
python
1>>> def convert_to_nbits_from_int(x, bits): 2... if x > (1<<(bits-1))-1 or x < -(1<<(bits-1)): 3... raise(ValueError(x)) 4... if x < 0: 5... x += 1 << bits 6... return x 7... 8>>> x=convert_to_nbits_from_int(0, 8); x, bin(x) 9(0, '0b0') 10>>> x=convert_to_nbits_from_int(1, 8); x, bin(x) 11(1, '0b1') 12>>> x=convert_to_nbits_from_int(127, 8); x, bin(x) 13(127, '0b1111111') 14>>> x=convert_to_nbits_from_int(128, 8); x, bin(x) 15Traceback (most recent call last): 16 File "<stdin>", line 1, in <module> 17 File "<stdin>", line 3, in convert_to_nbits_from_int 18ValueError: 128 19>>> x=convert_to_nbits_from_int(-128, 8); x, bin(x) 20(128, '0b10000000') 21>>> x=convert_to_nbits_from_int(-129, 8); x, bin(x) 22Traceback (most recent call last): 23 File "<stdin>", line 1, in <module> 24 File "<stdin>", line 3, in convert_to_nbits_from_int 25ValueError: -129 26>>> x=convert_to_nbits_from_int(-1, 8); x, bin(x) 27(255, '0b11111111') 28>>>
ただし、元々Pythonのビット演算は負値を2の補数で扱うため、
https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types
例外をあげないことにすれば単純に
python
1>>> def convert_to_nbits_from_int(x, bits): 2... return x & ((1 << bits) - 1) 3... 4>>>
と書くことができます。
逆にbits
ビットの2の補数で表現された任意の値x
を元の数値に戻すには、(質問にあるとおり)
python
1>>> def convert_to_int_from_nbits(x, bits): 2... return (-(x & (1<<(bits-1)))) | (x & ((1<<(bits-1))-1)) 3... 4>>> convert_to_int_from_nbits(255, 8) 5-1 6>>> convert_to_int_from_nbits(128, 8) 7-128 8>>> convert_to_int_from_nbits(127, 8) 9127 10>>> convert_to_int_from_nbits(1, 8) 111 12>>> convert_to_int_from_nbits(0, 8) 130 14>>>
のような形に書けます。
回答
上記の説明から、質問文のa
は243
という正の整数値であり、x
は115
という正の整数値です。
ただ最後にご質問されている数値には負数が混ざっており、そのビット演算は2の補数表現で行われるため、一度2の補数表現を使用した整数値に変換して全て正数演算するコードを以下に記述しました。
質問文の-0b10000000|x
は
python
1>>> convert_to_int_from_nbits(convert_to_nbits_from_int(-0b10000000,9) | convert_to_nbits_from_int(x,9), 9) 2-13
となります。
質問文の0b10000000|-x
は
python
1>>> convert_to_int_from_nbits(convert_to_nbits_from_int(0b10000000, 9) | convert_to_nbits_from_int(-x,9), 9) 2-115
となります。
質問文の-(0b10000000|x)
は
python
1>>> -convert_to_int_from_nbits(convert_to_nbits_from_int(0b10000000, 9) | convert_to_nbits_from_int(x,9), 9) 2-243
となります。
※9桁にしているのは、0b10000000=128
など8桁の2の補数では表現できない数字が出現するからです
投稿2021/10/28 12:34
編集2021/10/28 12:38退会済みユーザー
総合スコア0
0
python には、8ビットの型というのがないはずですから
8ビットの最上位ビットを 符号ビットとして特別扱いします。
python
1a = 0b11110011 2 3b = -(a & 0b10000000) | (a & 0b01111111) 4 5print(b)
で、-13 が出力されます。
一般化するには 関数化しちゃうのがいいかと思います。
詳細は
「Pythonで符号付き8bit整数を扱う(2の補数)」
をご参照ください(わたしも ここを読みました 笑)。
投稿2021/10/27 01:57
総合スコア1638
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/04 06:20