问题
I would like to be able to extract the significand and exponent of floating-point numbers in NumPy. Getting the exponent as an integer is fine and ok for the significand. Getting the significand as a bitfield would be even more convienient.
I am aware that Python floats have a hex
method; however, I wish to use numpy.float32
, numpy arrays, and ufuncs. I am also aware of the numpy view
method that allows me to see the float as an integer and thus as a binary string:
>>> import numpy as np
>>> b = bin(np.float32(1.23456789).view(np.int32))
'0b111111100111100000011001010010'
>>> b[-23:] # extract last 23 bits of IEEE 754 binary32 float, is significand
'00111100000011001010010'
Extracting the exponent and sign in this way is not convenient, as leading 0s are dropped by bin
. (I could left-pad to 32 bits with 0s though…)
In any case, because bin
is not a ufunc, this is not convenient and I would have to iterate over the array.
Isn't there any more convenient approach to doing what I want?
回答1:
GPhilio's comment triggered a more thorough search on SO which resulted in the following solution, based on an answer to “extracting mantissa and exponent from double in c#”:
import numpy as np
def decompose(x: np.float32):
"""decomposes a float32 into negative, exponent, and significand"""
negative = x < 0
n = np.abs(x).view(np.int32) # discard sign (MSB now 0),
# view bit string as int32
exponent = (n >> 23) - 127 # drop significand, correct exponent offset
# 23 and 127 are specific to float32
significand = n & np.int32(2**23 - 1) # second factor provides mask
# to extract significand
return (negative, exponent, significand)
This approach with bit-level operations of integers is actually more convenient that going to the actual bitstring itself.
来源:https://stackoverflow.com/questions/46093123/extracting-floating-point-significand-and-exponent-in-numpy