Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, how can I translate *(1+(int*)&x)?

This question is a follow-up of this one. In Sun's math library (in C), the expression

*(1+(int*)&x)

is used to retrieve the high word of the floating point number x. Here, the OS is assumed 64-bit, with little-endian representation.

I am thinking how to translate the C expression above into Python? The difficulty here is how to translate the '&', and '*' in the expression. Btw, maybe Python has some built-in function that retrieves the high word of a floating point number?

like image 309
zell Avatar asked Mar 15 '23 22:03

zell


1 Answers

You can do this more easily with struct:

high_word = struct.pack('<d', x)[4:8]
return struct.unpack('<i', high_word)[0]

Here, high_word is a bytes object (or a str in 2.x) consisting of the four most significant bytes of x in little endian order (using IEEE 64-bit floating point format). We then unpack it back into a 32-bit integer (which is returned in a singleton tuple, hence the [0]).

This always uses little-endian for everything, regardless of your platform's underlying endianness. If you need to use native endianness, replace the < with = (and use > or ! to force big endian). It also guarantees 64-bit doubles and 32-bit ints, which C does not. You can remove that guarantee as well, but there is no good reason to do so since it makes your question nonsensical.

While this could be done with pointer arithmetic, it would involve messing around with ctypes and the conversion from Python float to C float would still be relatively expensive. The struct code is much easier to read.

like image 195
Kevin Avatar answered Mar 25 '23 08:03

Kevin