Hola,
El 20/03/2013, a las 11:00, Chema Cortes escribió:
> Supongo que habrá una explicación. Si realizo el siguiente cálculo:
>
> In [13]: import math
>
> In [14]: math.tan(math.pi/2)
> Out[14]: 1.633123935319537e+16
>
> Aunque no esperaba que me diese la solución correcta de
> float("+inf")/float("-inf"), me resulta muy corto para el tamaño
> máximo que podría tener un double:
>
> In [16]: sys.float_info.max
> Out[16]: 1.7976931348623157e+308
>
> He comprobado que pasa lo mismo con scala e, incluso, en el buscador
> de google (tal vez sea que google usa también python):
>
> https://www.google.com/search?q=tan(pi%2F2)
>
> ¿Existe alguna explicación?
>>> import math
>>> math.pi/2.
1.5707963267948966
Aparentemente la tangente de ese número con esa precisión es exactamente esa
calculando con la precisión de un float.
Para aumentar la precisión creo que hay que usar una librería que ofrezca
precisión arbitraria como el módulo "decimal" de la librería estándar o mpmath.
El problema con "decimal" es que no implementa funciones matemáticas un poco
más complejas como las trigonométricas, así que el resultado de la tangente
sería el mismo si se usan las mismas funciones que antes.
>>> from decimal import Decimal
>>> pi_dec = Decimal('3.1415926535897932384626433832795028841971693993751')
>>> pi_dec
Decimal('3.1415926535897932384626433832795028841971693993751')
>>> pi_dec/Decimal('2')
Decimal('1.570796326794896619231321692')
>>> math.tan(pi_dec/Decimal('2'))
1.633123935319537e+16
Si no me equivoco, las funciones trigonométricas se suelen calcular usando
series. Una buena librería de precisión arbitraria (supongo que todas) irá
adaptando el número de sumandos a la precisión requerida. Por ejemplo:
>>> from mpmath import *
>>> tan(1.5707963267948966)
mpf('16331239353195370.0')
>>> tan(pi/2)
mpf('16331239353195370.0')
Aumentamos la precisión
>>> mp.dps = 50
>>> tan(1.5707963267948966)
mpf('16331239353195369.755967737041528916530864068104910291')
>>> tan(pi/2)
mpf('-1978834901269570871682051952580899049722178117311132.0')
>>> tan(mpf('1.5707963267948966192313216916397514420985846996875534'))
mpf('-1978834901269570871682051952580899049722178117311132.0')
> ¿Algún modo de ajustar más el resultado a
> infinito (sin ser la solución trivial de comprobar los parámetros de
> entrada)?
Creo que la única opción es usar un módulo matemático de precisión arbitraria
como mpmath o bigfloat.
Un saludo.
_______________________________________________
Python-es mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/