HZK
@HZK (Ritoku Sakamae)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

16進数のint型数値を、そのままの表記で元のint型に戻すことは可能ですか

解決したいこと

16進数のint型数値を、str型にする方法は複数ありますが、開始点である元のint型に戻すことができません。必ず10進数の数値になってしまいます。

また、これと関連しますが、16進数のint型数値を要素とするリストを、そのままの状態で出力する方法も分かりません。printすると10進数の要素となってしまいます。
色々調べましたが、分かりませんでした。

計算上不要ということは何となく理解できるので、表記上の疑問ともいえます。
もし、不可能だとするならば、16進数のint型数値に戻ることは、コード上はそもそも不要という考え方でしょうか。

必要性の有無の考え方も含めて、ご教授お願い致します。

該当するソースコード

# -*- coding: utf-8 -*-

#開始点
n = 0x3421
print(type(n))
#<class 'int'>

hn = hex(n)
print(hn)
print(type(hn))
#0x3421
#<class 'str'>

result = f'{n:#x}'
print(result)
print(type(result))
#0x3421
#<class 'str'>

h_lt = [0x0, 0x16, 0x15, 0x0, 0x6, 0x7, 0x14]
print(h_lt)
#[0, 22, 21, 0, 6, 7, 20]
0

5Answer

This answer has been deleted for violation of our Terms of Service.

int型は数値を保持するのみで、表記に関する情報は持ちません。

Pythonのint型は数値そのものを扱います。そのため、0xで始まる16進数のリテラルであっても、int型に変換されると10進数として内部的に扱われます。int型を文字列に変換した際には、どのように表現するか(10進数、16進数など)は出力時のフォーマット次第です。

1Like

Comments

  1. @HZK

    Questioner

    「int型は内部的には数値そのものであり、文字列はまさに表現の仕方によって複数存在する」よく理解できました。ありがとうございました。

16進数のint型数値を、str型にする方法は複数ありますが、開始点である元のint型に戻すことができません。必ず10進数の数値になってしまいます。

コンピューターの中では整数は 2 進数で、そこは何をどうしようと変わらず、10/16 進数うんぬんはプログラムでの書き方とかコンソールに表示するときなどにどういう形で表示するかの書式設定の問題ということは理解されてますか。

(追記: 上に書いた 2 進数というのは Python では違って、Python 独自の内部表現になるようですね。失礼しました)

文字列はそれとは違う話で、整数を文字列に変換すると 2 進数とは別の形、例えば Windows OS 内部では unicode (UTF−16) でメモリに保持されます。

1Like

Comments

  1. @HZK

    Questioner

    コンピュータにとって重要なのは2進数のみ。文字列は当然のこととして、16進数ですら人間の便益のために存在するのだということを、より深く理解できました。ありがとうございました。

興味深い話題なので、書いてみます。
基本は外の方の意見と同じです。

プログラミング言語には「リテラル」というデータの表現方法があります。「Hello」という文字列を表すリテラルは"Hello"だし、10進数の12を表すリテラルは12で、Bool値の真と偽からなるリストのリテラルは[True, False]です。これらのリテラルは、言語の仕様の一部であり、プログラムの記述が楽になうりょうに、直感的にそうだと思えるような表現になっていたり簡単な仕組みを持っていたりします。
また、リテラルによる表現は一意ではなく、同じオブジェクトを複数の方法で表わすことができる場合もあります。"world"'world'は同じ文字列を表わし、0x10と'16`は同じ数値を表わします。

ただ、ここで気をつけなければならないことは、リテラルがそのデータそのものを表わしているわけではないということです。プログラムの中にあるリテラルは、コンパイラーやインタープリタに読み込まれて、プログラムの内部表現に変換されます。pythonのデータはオブジェクト指向に基づいているので、メソッドや属性を持ったデータの塊になっています。
表面的な話をすれば、たとえば[True, False]というリストのリテラルには、「[]」や「,」が含まれていますが、リストの要素にはこれらのものは含まれません。文字列の「"」などについても同様です。
整数については、基数を変えた表現が使えます。単に数値を書くと基数は10(10進数)とみなされます。他の基数では、2, 8, 16が使え、それぞれ、0b10000o100x8とあらわせますが、すべて10進数の「8」と同じもので、同じオブジェクトが生成されます。また、生成されたオブジェクトには、どのようなリテラルから生成されたものなのかという情報は含まれていません。

ということで、質問にある、「16進数のint型数値」とか「10進数のint型数値」というものは存在しないといくとおちぃなります。

内部のオブジェクトを出力するときにも、いろいろな仕組みが働いています。
変数には、リテラルそのものではなくそこから作られたオブジェクトが入っているわけで、そのオブジェクトをprintで出力しようとしたときにどのようになるかについては、オブジェクトの仕様によって異なります。そのオブジェクトがリストであれば、要素をカンマで区切り、前後を「[]」でくくって出力します。 これはリテラルの表現と同じです。文字列であれば、構成する文字をすべてそのまま出力します。これはリテラルの表現とは異なります。

整数の場合は、10進数として表示します。
「16進数のint型数値」が「10進数のint型数値」になってしまったように見えるのはこのためでしょう。

1Like

Comments

  1. @HZK

    Questioner

    「0x10, 16も同一のint型オブジェクトで、リテラルが違うだけ」
    参考書では読み飛ばしてしまう説明も、この場で解説して頂くと理解が深まるのには驚くばかりです。ありがとうございました。

>>> n = 0x3421  # 16進数整数リテラル、int型オブジェクト、内部はバイナリ(2進数)データ
>>> print(n)  # 10進数表示
13345
>>> print(hex(n))  # 16進数表示
0x3421
>>> s = hex(n)  # 16進数文字列に変換
>>> type(s)
<class'str'>
>>> print(s)  # 16進数文字列表示
0x3421
>>> i = int(s, 16)  # 16進数文字列をint型整数に変換
>>> print(i)
13345
>>> print(hex(i))
0x3421
>>> h_lt = [0x0, 0x16, 0x15, 0x0, 0x6, 0x7, 0x14]
>>> print(f'[{", ".join(map(hex, h_lt))}]')  # 要素を16進数文字列変換にマップして連結
[0x0, 0x16, 0x15, 0x0, 0x6, 0x7, 0x14]
0Like

Your answer might help someone💌