2017-02-01 4 views
1

Comment travailler avec l'équivalent de __float128 en Python? Quelle précision dois-je utiliser pour decimal.getcontext()? Je veux dire, la précision est-elle spécifiée en décimales ou bits?Equivalent de float128

from decimal import * 
getcontext().prec = # 34 or 128 ? 

Est-il possible de définir la précision « localement » pour une opération donnée, plutôt que de le mettre « à l'échelle mondiale » avec getcontext().prec? Par commentaire de Simon Byrne, est-il même possible de simuler __float128 comme défini par IEEE 754 avec Decimal? Quelles autres options ai-je en Python, si je voulais une quadruple précision?

+1

Je pense que vous trouverez vos réponses dans [la documentation] (https://docs.python.org/3/library/decimal.html). – vaultah

+0

@vaultah J'ai consulté la documentation à l'avance, oui, mais je voulais m'assurer de bien la comprendre. Je voulais vérifier si '.prec' définissait vraiment des positions ** décimales **, par exemple ... –

+0

' decimal' est une implémentation de virgule flottante décimale, donc '.prec' est une position décimale. Cela vous donnera des réponses différentes de '__float128', qui est un format binaire. –

Répondre

2

Je suis le mainteneur de gmpy2. Outre l'encapsulation MPFR, gmpy2 enveloppe également GMP (pour les nombres entiers et rationnels) et MPC (pour l'arithmétique complexe). Les deux MPFR et MPC utilisent une représentation binaire par rapport à Decimal qui utilise une représentation décimale.

Voici un exemple rapide montrant l'utilisation de l'équivalent de float128.

>>> import gmpy2 
>>> gmpy2.set_context(gmpy2.ieee(128)) 
>>> gmpy2.get_context() 
context(precision=113, real_prec=Default, imag_prec=Default, 
     round=RoundToNearest, real_round=Default, imag_round=Default, 
     emax=16384, emin=-16493, 
     subnormalize=True, 
     trap_underflow=False, underflow=False, 
     trap_overflow=False, overflow=False, 
     trap_inexact=False, inexact=False, 
     trap_invalid=False, invalid=False, 
     trap_erange=False, erange=False, 
     trap_divzero=False, divzero=False, 
     trap_expbound=False, 
     allow_complex=False) 
>>> gmpy2.sin(gmpy2.mpfr("1.2")) 
mpfr('0.932039085967226349670134435494826026',113) 

Pour la série 2.0.x, gmpy2.ieee() ne crée que des contextes de support 32, 64 ou 128 bits formats. Les branches de la branche de développement sont plus large gamme de précisions.

+0

Btw., Savez-vous à quel point lent IEEE soft float128 est comparé à la double précision du matériel? –

+0

@EcirHana Je commencerais par supposer 10x plus lent mais cela dépend de l'opération. Je peux faire des benchmarks plus tard. – casevh

1

Malheureusement, Python prend en charge nativement un seul type de virgule flottante, le type double de l'architecture sous-jacente.

En fonction de l'architecture, numpy peut déclarer un float128, mais il est connu pour ne pas être disponible de manière cohérente.

Si vous en avez besoin en dehors de numpy, (ou sur une plateforme où numpy ne le supporte pas), vous pouvez jeter un oeil sur le bigfloat package on pypi qui est un wrapper autour de GNU MPFR library. Mais attention, il est actuellement déclaré au niveau bêta et vous devez être prêt à le construire à partir de sources.


Après @ commentaire de MarkDickinson (il est l'auteur de BigFloat), gmpy2 est une autre enveloppe autour MPFR qui est déclarée stable sur pypi et est à la fois plus riche et mieux entretenu.

+0

En tant qu'auteur de 'bigfloat', je recommande aux gens de jeter un oeil à' gmpy2' à la place. :-) Il est mieux maintenu, et fait le même travail d'emballage MPFR (et plus). –

+0

BTW, savez-vous de toute plate-forme où 'float128' de NumPy est vraiment le type IEEE 754 binary128 (par opposition à double-double, ou un type float80 zéro-rembourré)? –

+0

@MarkDickinson: merci pour votre commentaire! Je l'ai inclus dans mon message. Malheureusement, je ne suis pas un grand utilisateur numpy ... –