with tutorial functions engineering python numpy numerical-methods

python - tutorial - ¿Hay algún significado especial para 16331239353195370.0?



numpy python download (1)

Usando import numpy as np , he notado que

np.tan(np.pi/2)

da el número en el título y no np.inf

16331239353195370.0

Tengo curiosidad por este número. ¿Está relacionado con algún parámetro de precisión de la máquina del sistema? ¿Podría haberlo calculado a partir de algo? (Estoy pensando en algo similar a sys.float_info )

EDITAR: El mismo resultado es reproducible en otros entornos como Java, octace, matlab ... Sin embargo, el engaño sugerido no explica por qué.


pi no es exactamente representable como Python float (igual que el tipo double la plataforma C). Se utiliza la aproximación representable más cercana.

Aquí está la aproximación exacta en uso en mi caja (probablemente la misma que en su caja):

>>> import math >>> (math.pi / 2).as_integer_ratio() (884279719003555, 562949953421312)

Para encontrar la tangente de esa relación, voy a cambiar a wxMaxima ahora:

(%i1) fpprec: 32; (%o1) 32 (%i2) tan(bfloat(884279719003555) / 562949953421312); (%o2) 1.6331239353195369755967737041529b16

Esencialmente idéntico a lo que tienes. La aproximación binaria a pi/2 utilizada es un poco menor que el valor matemático ("precisión infinita") de pi/2 . Entonces obtienes una tangente muy grande en lugar de infinity . ¡El tan() calculado tan() es apropiado para la entrada real!

Por exactamente el mismo tipo de razones, por ejemplo,

>>> math.sin(math.pi) 1.2246467991473532e-16

no devuelve 0. La aproximación math.pi es un poco menor que pi , y el resultado mostrado es correcto dada esa verdad.

OTRAS MANERAS DE VER math.pi

Hay varias formas de ver la aproximación exacta en uso:

>>> import math >>> math.pi.as_integer_ratio() (884279719003555, 281474976710656)

math.pi es exactamente igual al valor matemático ("precisión infinita") de esa relación.

O como un flotador exacto en notación hexadecimal:

>>> math.pi.hex() ''0x1.921fb54442d18p+1''

O de una manera más fácil de entender para casi todos:

>>> import decimal >>> decimal.Decimal(math.pi) Decimal(''3.141592653589793115997963468544185161590576171875'')

Si bien puede no ser inmediatamente obvio, cada flotante binario finito es exactamente representable como un flotante decimal finito (lo inverso no es cierto; por ejemplo, el decimal 0.1 no es exactamente representable como un flotante binario finito), y el constructor Decimal(some_float) produce El equivalente exacto.

Aquí está el verdadero valor de pi seguido del valor decimal exacto de math.pi , y un math.pi intercalación en la tercera línea apunta al primer dígito donde difieren:

true 3.14159265358979323846264338327950288419716939937510... math.pi 3.141592653589793115997963468544185161590576171875 ^

math.pi es el mismo en "casi todos" los cuadros ahora, porque casi todos los cuadros ahora usan el mismo formato binario de punto flotante (precisión doble IEEE 754). Puede usar cualquiera de las formas anteriores para confirmar eso en su caja, o para encontrar la aproximación precisa en uso si su caja es una excepción.