Check the binary digital of variable in memory

Hi,

On Windows 10, I am using Pycharm to debug code.
My example code is:

a=3.25
b=int(a)

as we know, it is very easy for us the get the address of a and b, and then check the binary digit in memory in C language.
I would like to check what the binary digital of a and b in memory is in Python.
how to do that?

[quote Ardeal]
“as we know, it is very easy for us the get the address of a and b, and then check the binary digit in memory in C language.”
[end quote]

I don’t know who “we” is, but I don’t know what you mean.

Do you mean showing the numbers in base 2 (binary) instead of base 10 (decimal)?

Python supports base conversion to binary for integers, and we can get the hexadecimal (base 16) representation of floats:

a = 3.25
b = int(a)
a.hex()  # returns '0x1.a000000000000p+1'
bin(b)  # returns '0b11'

Converting hex into binary is left as an exercise. (Hint: 3.25 in binary will be 11.01.)

Is that what you mean?

@steven.daprano

Thank you for you reply!
The method you mentioned is not what I want to know.
Please check the following c code:
I want to do similar thing in Python as C

For the following C code, we could check the binary number of float a in memory, which is very easy in C language. I suspect you know that.

float a = 3.25;
unsigned in address_a = (unsigned int)(&a)

A second thought comes to mind… maybe you mean this?

https://docs.python.org/3/library/struct.html

struct.pack('d', a)  # returns b'\x00\x00\x00\x00\x00\x00\n@'
struct.pack('l', b)  # returns b'\x03\x00\x00\x00\x00\x00\x00\x00'

Because the internal format of machine types may be different on different platforms, you may not get exactly the same results.

This is a Python forum, not a C forum. Please don’t assume that Python programmers are expert in C.

I have no idea what your C code does.

Also, it is not safe to assume that Python objects have a fixed address. In at least two Python interpreters, and probably more, objects can move around in memory at any time. The Python language does not define any sort of “get the address of this object” function or operator.

Some people will tell you that you can use id(). That is wrong. It is not portable: in Jython and IronPython, id() returns consecutive values 1, 2, 3, 4, 5, 6, … as needed.

If I am not wrong this creates a new C struct content representing the given values. It is limited to just the simple C data types: struct — Interpret bytes as packed binary data — Python 3.10.5 documentation The bytes may be different from the real representation of the Python object’s value in memory.

To access the real bytes in memory containing a Python object you would need to write a C extension for that. This is not normally needed in Python so there is probably no such a maintained extension. This has been covered in this question:

@vbrozik
Thank you!

It looks like struct.pack is the closest solution for my question.

I’m curious, @ardeal, are you wanting to look at the raw contents of the variable’s memory address or just convert to binary?

I ask because looking at the native binary would be faster than a conversion in some languages. Not sure if that’s the case for Python (and it’s very doubtful from what Steven D’Aprano said in the post above).

@mlgtechuser ,

what I want to do is to look at the raw contents in variable’s memory. I don’t want to convert the variable to binary.
In my post, I gave an example about how I look at the raw contents in variable’s memory in C language.

according to those upper guys explanation, in python, it is not easy the look at the raw content in variable’s memory.

Your first problem is working out how to get the address of a variable.

Variables don’t have an address in Python. Only objects have addresses, and there is no supported way to get an object’s address. In CPython you can use id() and hope that the implementation hasn’t changed, but that’s not portable. In Jython, IronPython and maybe PyPy you are out of luck.

Once you have the address, you can probably write a C extension to dump the raw bytes of an object. But why? What are you planning to do with it?

https://docs.python.org/3/c-api/index.html

1 Like

You can use numpy for this:

import numpy as np

a = np.float64(3.25)
b = a.view(np.uint64)
1 Like

I am not much familiar with numpy. I tried to find the method numpy.float64.view() in the documentation but I gave up. Can you please point me to this method’s description?

The docs say:

Array scalars have the same attributes and methods as ndarrays.

Here is the documentation of view()

1 Like

I used this function last Fall on a vision project to work with a cropped part of an image (or at least considered using it; I’d have to look up the code). view() is a virtualized child object of the array, showing only part of the data. [EDIT: ] Perhaps better stated as “a view() is a pointer to part of an existing array.”

It’s actually on the other side of the array object from the hardware register, so is farther away.

Hi,

For the following code, the first byte should be x55, but it is U, why?

    a = 2**0 + 2**2 + 2**4 + 2**6 + 2**8 + 2**10
    c = struct.pack('I', a)

b'U\x05\x00\x00'

"U" and "\x55" is one and the same byte/character. Try this in the REPL:

>>> 'U' == '\x55'

See also the ASCII table. If you are on Linux or macOS, you can type man ascii in a terminal.

1 Like

'U' is '\x55':

assert 'U' == '\x55'

When the byte is a printable ASCII character it is shown as the ASCII character.

Maybe you want to print the bytes as hexadecimal?

b'U\x05\x00\x00'.hex()

gives

'55050000'

Yes, c = struct.pack('I', a).hex() works for me.