Disons que j'ai deux flotteurs Python a
et b
, est-il un moyen facile de trouver combien de nombres réels représentables sont entre les deux dans la représentation IEEE-754 (ou quelle représentation la machine utilisée utilise)?Nombre de flottants entre deux flotteurs
Répondre
Je don'tknow ce que vous allez utiliser cela pour - mais, si les deux flotteurs ont le même exposant, cela devrait être possible. Comme l'exposant est conservé sur les bits de poids fort, le chargement des octets flottants (8 octets dans ce cas) sous la forme d'un entier et la soustraction de l'un par rapport à l'autre devrait donner le nombre que vous voulez. J'utilise le modèle struct pour emballer les flotteurs à une représentation binaire, puis déballer ceux que (C, 8 octets) longue ints:
>>> import struct
>>> a = struct.pack("dd", 1.000000,1.000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503599627
>>> a = struct.pack("dd", 1.000000000,1.000000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503600
>>>
s'avère que l'exposant n'a pas d'importance, mais le signe fait. –
+1; Bonne réponse. Cependant, cela ne fonctionnera pas sur les systèmes avec un C de 32 bits. Pour être du bon côté, utilisez "
Pour être complet, vous pouvez également mentionner que cette solution ne fonctionne que pour les formats IEEE 754. En pratique, ce n'est pas vraiment une restriction, cependant --- il est très difficile de trouver Python en cours d'exécution sur une plate-forme utilisant des doublures non IEEE 754. –
pour les nombres positifs b> a> 0, la réponse est environ:
(2**52) ** (log(b,2) - log(a,2))
Il y a 52 bits de mantisse (au-delà du implicite 1), multiplié par 2 élevé à un exposant.
Donc, il y a 2 ** 52 numéros dans la tranche [1: 2) dans la plage [1024: 2048)
La théorie est bonne - mais ça ne marche pas pour moi quand les nombres flottants sont trop proches. Probablement en raison du fait que le calcul du journal introduit lui-même un arrondi. – jsbueno
AFAIK, flotteurs IEEE754 ont une propriété intéressante. Si vous avez float f, alors
(*(int*)&f + 1)
sous certaines conditions, est le nombre à virgule flottante représentable suivant. Donc, pour les flotteurs a et b
*(int*)&a - *(int*)&b
vous donnera la quantité de nombres à virgule flottante entre ces chiffres. Pour plus d'informations, voir http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm pour plus d'informations.
La seule exigence est qu'ils aient le même signe, Nan et inf non plus. –
On dirait que c'est * la * réponse à la question, mais une partie manque: comment fait-on cela en Python? – Bolo
Bien que cela ne répond pas à la question pour Python, c'est une très bonne réponse. Mon manuel sur "Méthodes de calcul" est également d'accord avec cela. Quelqu'un sait-il un moyen de convertir cela en Python? – Dragontamer5788
Je regarderais la fonction frexp dans le module mathématique. L'exemple ci-dessous extrait la mantisse et la convertit en entier. La différence devrait être le nombre de flottants entre les deux valeurs.
>>> math.frexp(1.1234567890)[0] * 2**53
5059599576307254.0
>>> math.frexp(1.12345678901)[0] * 2**53
5059599576352290.0
Le code suivant devrait le faire:
import math
import sys
def delta(x,y):
'''Return the number of floats between x and y.'''
x = float(x)
y = float(y)
if x == y:
return 0
elif x < y:
return -delta(y,x)
else:
x_mant, x_exp = math.frexp(x)
y_mant, y_exp = math.frexp(y)
x_int = int(x_mant * 2**(sys.float_info.mant_dig + x_exp - y_exp))
y_int = int(y_mant * 2**sys.float_info.mant_dig)
return x_int - y_int
print(delta(1.123456789, 1.1234567889999))
450
>>>
Juste par curiosité, quel besoin avez-vous ces informations pour? –
Comment voulez-vous dire? Deux flotteurs spécifiques ou généralement? Et voulez-vous être capable de le faire à partir de python ou voulez-vous faire les calculs manuellement? – terminus
Je veux comparer deux nombres à virgule flottante pour déterminer s'ils sont égaux à une précision proche de la précision de la représentation mais non égale à celle-ci. Je suis intéressé à faire cela en Python. Voir la fonction AlmostEqual2sComplement à http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - Je sais que je peux le faire avec des choses comme (ab)/a
astrofrog