2017-09-07 5 views
1

Je voudrais pouvoir extraire le significand et l'exposant des nombres à virgule flottante dans NumPy. Obtenir l'exposant comme un nombre entier est bien et ok pour le significand. Obtenir le significand comme un champ de bits serait encore plus pratique. Je sais que les flotteurs Python ont une méthode hex; cependant, je souhaite utiliser numpy.float32, les tableaux numpy et les ufuncs. Je suis également au courant de la méthode view numpy qui me permet de voir le flotteur comme un entier et donc comme une chaîne binaire:Extraction du significand et de l'exposant en virgule flottante dans NumPy

>>> 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' 

Extraction de l'exposant et signe de cette manière est pas pratique, comme les principaux 0s sont lâchés par bin. (Je pourrais gauche à 32 bits avec 0s si ...)

Dans tous les cas, parce que bin n'est pas un ufunc, ce n'est pas pratique et je devrais itérer sur le tableau.

N'y a-t-il pas une approche plus pratique pour faire ce que je veux?

+1

Jetez un oeil à [cette réponse] (https://stackoverflow.com/a/16444786/3214872), il pourrait vous pointer dans la direction droite – GPhilo

+1

@GPhilo: Merci. En fait, cette réponse semble indiquer clairement que non, il n'y a pas d'approche plus pratique. – equaeghe

+1

Jetez un coup d'œil à ['numpy.frexp'] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.frexp.html) –

Répondre

1

commentaire de GPhilio a déclenché une recherche plus approfondie sur le SO qui a abouti à la solution suivante, basée sur 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) 

Cette approche des opérations au niveau du bit d'entiers est en fait plus pratique que d'aller à la bitstring réelle lui-même.