Math.cos (Math.PI / 2) devuelve 6.123031769111886e-17 en JavaScript y AS3?

Si entiendo esto correctamente, tanto JavaScript como ActionScript 3 funcionan con radianes.

Entonces, la salida esperada de los siguientes códigos sería:

Math.PI                 //Expected 3.141592653589793, got 3.141592653589793

Math.sin(0)             //Expected 0, got 0
Math.sin(Math.PI/2)     //Expected 1, got 1
Math.sin(Math.PI)       //Expected 0, got 1.2246063538223773e-16
Math.sin(Math.PI*3/2)   //Expected -1, got -1
Math.sin(Math.PI*2)     //Expected 0, got -2.4492127076447545e-16

Math.cos(0)             //Expected 1, got 1
Math.cos(Math.PI/2)     //Expected 0, got 6.123031769111886e-17
Math.cos(Math.PI)       //Expected -1, got -1
Math.cos(Math.PI*3/2)   //Expected 0, got -1.836909530733566e-16
Math.cos(Math.PI*2)     //Expected 1, got 1

Este es el mismo comportamiento en Firefox, Chrome, Safari y también en Flash Professional CS5.5. Estoy usando Mac OS X 10.7.2.

Prueba:

http://jsfiddle.net/KA4VM/

preguntado el 08 de noviembre de 11 a las 12:11

¿Y el problema es? Los 0 están muy cerca de 0. Diría que solo es una cuestión de precisión. Nada mal. -

No deberías esperar que pi sea exactamente 3.141592653589793 en primer lugar, si desea que sin / cos devuelva valores exactos. -

5 Respuestas

¿Ha mirado el valor que está obteniendo? Esperas 0, pero obtienes algo como

0.00000000000000012246063538223773

¿No es eso lo suficientemente cerca de cero para ti?

Básicamente, no debería esperar que las operaciones binarias de coma flotante sean exactamente justo cuando sus entradas no se pueden expresar como valores binarios exactos, lo que pi / 2 no puede, dado que es irracional. (No debe esperar que los resultados sean exactos incluso cuando las entradas se pueden expresar exactamente en binario, si la salida no se puede expresar exactamente ...)

respondido 08 nov., 11:16

Pero, ¿no será mucho más intensivo en recursos calcular con 6.123031769111886e-17 luego con 0? - Frithjof

Perdí 5 minutos tratando de entender por qué obtenía Math.cos (1.57) = 0.0007 .. y Math.cos (Math.PI / 2) = 6.12 ... Tuve que venir aquí para notar que hay un "e-17 " al final... - Artur Carvalho

Considere que estos errores son todos menores que 1e-15, que está alrededor 2**(-50), entonces podemos sumar y luego restar un número con magnitud 2**3 para redondear el resultado. Entonces, si elegimos 8 como número, podríamos redefinir sin y cos de la siguiente manera:

function sin(x) {
  return Math.sin(x) + 8 - 8;
}

function cos(x) {
  return Math.cos(x) + 8 - 8;
}

Esto debería completar el error y es más rápido que toFixed método.

Respondido 21 Abr '17, 22:04

Math.PI no es una representación 100% precisa de pi, simplemente porque pi es irracional y los números de coma flotante solo llegan hasta cierto punto.

Entonces, debido a los errores de redondeo, obtiene números extremadamente pequeños (sus números son #. ##### e-16 y #. ##### e-17, que son pequeños).

No puedes hacer nada al respecto, pero acepta que 0.000000000000000006 está lo suficientemente cerca de 0.

respondido 08 nov., 11:17

Debido a que PI es un número irracional (Número real sin ser Racional, es imposible calcular con un valor exacto. Como dijo Jon Skeet, los métodos trigonométricos del objeto Math solo obtienen valores aproximados para PI y devuelven un valor aproximado. Si el retorno de Los valores cero son importantes para su código, debe redondearlos. En casos como ese, extiendo esos objetos Javascript por métodos propios para mayor comodidad:

Math.Sin = function(w){         
    return parseFloat(Math.sin(w).toFixed(10));
};

Ahora mientras te quedas con

Math.sin(Math.PI)

este extraño resultado

> 1.2246467991473532e-16

obtienes con lo que esperabas

Math.Sin(Math.PI)
> 0

Haz lo mismo con las otras funciones trigonométricas:

Math.Cos = function(w){ 
    return parseFloat(Math.cos(w).toFixed(10));
};

y así sucesivamente.

Respondido el 25 de diciembre de 15 a las 01:12

Eso devolverá 1/0 para Math.PI/4. Deberías usar parseFloat(Math.sin/cos(w).toFixed(eg 5)). - klenio

Gracias @klenium. He editado mi publicación siguiendo tu propuesta. - Sedat Kilinc

Entonces tienes 1.xxxxx * 10 ^ -16

Esto sería 0.0000000000000001xxx (quince ceros después del punto decimal)

Apuesto a que eso es lo suficientemente cerca de cero para considerarlo como 0.

Obtienes ese error infinitesimal debido al error en el valor de pi (como debes saber, se extiende a dígitos infinitos después del punto decimal)

Sin embargo, no ha mencionado si obtiene esto en AS3 o JavaScript.

respondido 08 nov., 11:17

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.