LoginSignup
0
0

More than 3 years have passed since last update.

Python で浮動小数点数 float のメモリ上のバイト列を確認してみる

Last updated at Posted at 2020-07-08

※注(py3はもっとシンプルな方法があった)

>>> import ctypes
>>> f = ctypes.c_float(0.5)
>>> f
c_float(0.5)
>>> memoryview(f).tobytes()
b'\x00\x00\x00?'

>>> memoryview(f).cast('B', shape=(4,))[3] = 0x3e
>>> f
c_float(0.125)
>>> memoryview(f).cast('B', shape=(4,))[3] = 0x40
>>> f
c_float(2.0)
>>> memoryview(f).cast('B', shape=(4,))[:] = bytes([0x3a, 0xcd, 0x13, 0xbf])
>>> f
c_float(-0.5773502588272095)

ctyes の使い方をいつも忘れるのでメモ。
a = 0.5 のときの a のメモリ上のバイト列を観たい。

>>> import ctypes
>>> a = ctypes.c_float(0.5)
>>> a
c_float(0.5)
>>> a.value
0.5
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_float))
<__main__.LP_c_float object at 0x000001FF2A2F59C8>
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_char))
<ctypes.LP_c_char object at 0x000001FF2A2F5B48>
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_char))[0:4]
b'\x00\x00\x00?'

[0:4] で範囲指定しておかないと怒られる。([:]だとエラー)
出力が判り易い様に修正。

>>> b = lambda f: [f'{b:02x}' for b in ctypes.cast(ctypes.byref(ctypes.c_float(f)), ctypes.POINTER(ctypes.c_char))[0:4]]
>>> b(0.5)
['00', '00', '00', '3f']

ついでにその他の数値は、

>>> b(0.25)
['00', '00', '80', '3e']
>>> b(0.866)
['2d', 'b2', '5d', '3f']
>>> b(0.433)
['2d', 'b2', 'dd', '3e']
>>> b(0.216)
['1b', '2f', '5d', '3e']
>>> b(0.0)
['00', '00', '00', '00']
>>> b(1.0)
['00', '00', '80', '3f']

逆も確認(バイト列から float)。

>>> f = lambda b: ctypes.cast(ctypes.create_string_buffer(b), ctypes.POINTER(ctypes.c_float))[0]
>>> f(b'\x2d\xb2\x5d\x3f')
0.8659999966621399
>>> f(b'\x2d\xb2\xdd\x3e')
0.43299999833106995
>>> f(b'\x2d\xb2\x5d\x3e')
0.21649999916553497
>>> f(b'\x3a\xcd\x13\xbf')
-0.5773502588272095
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0