Por que o Spotlight fornece um valor errado para `cos (pi / 2)`?

8

Como você deve saber, o Spotlight pode fazer matemática simples. Por exemplo, a digitação cos(pi)resultará em -1, como você poderia esperar. Eu apenas digitei cos(pi/2), que deveria ser 0, mas isso me deu -5e-12.

Sim, é provavelmente devido a um erro de arredondamento, mas vamos lá cos(pi/2):! Na minha opinião, isso claramente parece bug. O que você acha?

poitroae
fonte
1
cos (x) é uma função transcendental. A menos que eles codifiquem valores para pi, pi / 2, etc, você deve esperar algum erro.
Navin
@ Navin, na verdade, espero que eles codifiquem esses valores, pois são muito importantes.
poitroae
1
piem si seria codificado (à medida que você obtém -1 cos(pi)), mas assim que você o manipula, obtém um número de ponto flutuante, que tem precisão limitada. OSX não codifica pi/2, pi/4etc, ele realmente faz a operação.
harryg
2
@harryg Embora haja erros de arredondamento que podem ser resolvidos com a mudança para decimal, este não é um deles. Decimal é útil se você deseja representar 0.1exatamente. precisamente, mas não é útil para números irracionais como pi, que não podem ser representados exatamente em binário ou decimal.
CodesInChaos
1
Para referência, em Ruby:irb(main):009:0> Math.cos(Math::PI/2) => 6.123233995736766e-17
harryg

Respostas:

13

Isso se deve à falta de precisão do pi e à falta geral de precisão no sistema interno.

pi = 3.1415926536

pi/2 = 1.5707963268 

cos(1.5707963268) = -5.103412e-12

FYI =  5.103412e-12 = 0.000000000005103412 ~ 0 


Sobre a precisão geral do sistema:

3.141592653589793238462643383 = 3.1415926536 

No Python, temos o seguinte:

>>> float("3.141592653589793238462643383")
3.141592653589793

Como podemos ver, há um problema com a precisão, pois ela nem sequer corresponde à representação de flutuação.

Matthieu Riegler
fonte
Isso se deve à falta de precisão, mas um erro dessa magnitude não pode ser atribuído aos números de ponto flutuante.
Dennis Jaheruddin
2
Provavelmente mais falta de precisão com o valor pi.
Matthieu Riegler 12/03
5

Eles não estão armazenando π com precisão incomum de ponto flutuante. Eles estão usando um valor incorreto para π com precisão dupla. Para aproximar 3,1415926536 em binário, são necessários pelo menos 38 bits:

3.14159265359922… > 11.001001000011111101101010100010001001

Observe que 2 ^ -36 é aproximadamente 1,5e-11, o que coincide com o 99 final. O ponto flutuante de precisão dupla tem um significando de 52 bits. Para avaliar cos(pi/2)como -5e-12, a única outra opção possível seria um tipo de 48 bits, o que seria muito estranho.

Perto de 0 e π, onde a derivada é quase zero, cos (θ) não pode ser calculado com muita precisão:

cos(3.1415926536) ≈ -0.999999999999999999999947911

Isso difere de -1 em cerca de 5,2e-23, que é menor que ε para double, então cos(3.1415926536)é calculado exatamente como -1 ... o que está incorreto.

Perto de ± π / 2, a derivada [ -sin (θ) ] é quase ± 1, portanto o erro na entrada se torna a saída.

cos(1.57079632679961) ≈ -4.71338076867830836e-12
cos(1.57079632679962) ≈ -4.72338076867830836e-12
cos(1.57079632680000) ≈ -5.10338076867830836e-12

Por acaso, tenho uma calculadora de TI que exibe um dígito a menos e calcula cos(π/2)como -5.2e-12. No entanto, é muito diferente eletronicamente e foi projetado para fornecer um valor exato para cos(90°).

Suponho que, no Spotlight, cos(pi/2)esteja sendo calculado recuperando um valor para π, convertendo para uma sequência decimal , armazenando-o como o valor binário (exato, racional) 11.001001000011111101101010100010001001000010011101111 (ou 10000), dividindo por 2 e depois subtraindo-o de o valor verdadeiro de π / 2. Você deve descobrir se cos(pi/2 + cos(pi/2))está mais perto de zero (pode ser -2,2e-35).

A multiplicação por uma potência de dois deve afetar apenas o expoente, não o significando. Pode ser possível determinar como o arredondamento é aplicado pela metade ou duplicação repetidas.

user130144
fonte
Nada está errado com o Markdown - o MathJax é ativado apenas em sites relacionados à matemática, e não em todo o SE.
grg
1
cos (pi / 2 + cos (pi / 2)) é exibido como 0 exatamente.
Nick Matteo
4

É um bug reproduzível na versão 10.9.2 - e um erro de arredondamento de ponto flutuante como esse é bastante típico.

É o valor de pi que está sendo tratado sem precisão suficiente, se eu tivesse que adivinhar.

  • cos (999999 * pi) não tem um erro
  • cos ((999999 + 1) * pi) tem um erro - provavelmente arredondamento

Eu diria para https://developer.apple.com/bug-reporting/ se você quiser ver o aparelho de correção de bugs da Apple em ação.

bmike
fonte
5
É realmente um bug? Qual deve ser a precisão dessa operação?
Édouard
Eu não sou um desenvolvedor registrado, mas ficaria muito grato se você pudesse enviá-lo para nós!
poitroae
4
@ Édouard Você pode considerar um erro se o usuário for levado a esperar alguma capacidade para matemática simbólica. Qualquer sistema de álgebra computacional (CAS) certamente saberá que cos (π / 2) = 0 exatamente! Por outro lado, não é razoável esperar que o Spotlight contenha um CAS. E no campo da aritmética de ponto flutuante, são esperados resultados como os relatórios do OP. Qualquer relatório de bug pode ser melhor rotulado como uma solicitação de recurso, talvez.
Harald Hanche-Olsen,
1
@ Édouard bmike está de fato correto que este é um bug e não apenas um erro de arredondamento. A precisão esperada de tal operação, dada a aritmética de precisão dupla padrão, é de cerca de 10 ^ -16, não de 10 ^ -12. Você pode tentar fazer isso escrevendo um programa em seu idioma favorito que aproveita o suporte ao ponto flutuante da CPU, fazendo o cálculo e examinando o padrão de bits do resultado. Como bmike diz, o motivo provável é que o valor π que o Spotlight usa não é definido com precisão suficiente.
Szabolcs
2
Algo estranho está acontecendo aqui. cos(2*acos(0)*0.5)retorna um número de pedido 10^-10. Portanto, não é porque a constante π não seja suficientemente precisa. Não posso explicar esse resultado: é impreciso demais para precisão dupla e muito preciso para precisão única.
Szabolcs
4

Das outras respostas e comentários, fica claro o seguinte:

O fato de você obter um resultado diferente de zero NÃO é um erro, mesmo com uma implementação perfeita do software, você se depararia com os limites dos cálculos de ponto flutuante. No entanto, o erro da ordem de 10 ^ -12 é realmente grande.

Isso NÃO é o culpado pela imprecisão dos números de ponto flutuante. O resultado obtido é exatamente este:

cos(1.5707963268)

Isso pode ser validado usando qualquer pacote de software alternativo. Se você avaliar cos(pi/2)em um desses pacotes, obterá definitivamente um resultado muito mais próximo de zero do que 10 ^ -12.

Para concluir, vejo duas possíveis limitações, uma das quais deve ser aplicada:

  1. Pi não é armazenado com precisão suficiente ou pelo menos pi / 2 resulta em precisão insuficiente
  2. Porque simplesmente leva precisão insuficiente como entrada

Talvez alguém com acesso ao software possa validar qual deles se aplica.

Atualização Conforme mencionado no comentário, o problema parece ser a precisão da constante pi.

Dennis Jaheruddin
fonte
Isso é estranho. 1.5707963268 é o resultado que o Spotlight fornece quando você calcula pi / 2. Após algumas tentativas simples, parece que o Spotlight exibe 10 dígitos significativos para números abaixo de 1 e 11 para números acima de 1. Mas por que motivo estranho de implementação uma etapa de arredondamento seria aplicada dentro da computação em vez de depois?
Édouard
1
Eu também queria ressaltar que, se você fornecer ao Spotlight uma aproximação pi / 2 mais precisa (colando mais de 10 dígitos do Wolfram Alpha, por exemplo), a precisão aumentará.
Édouard
Obrigado por confirmar meu palpite de que a precisão de pi foi a causa do erro entre 0 e aproximadamente 10 ^ -12 na pergunta do OP.
bmike
Quantas vezes você vê o seguinte: "10 ^ -12 é muito grande"
GEdgar
2

Considerando que -5e-12é um número muito pequeno, esse é um erro de arredondamento.

Eu acho que é a conseqüência do spotlight mostrar mais casas decimais do que as usadas na definição da piconstante ou da série infinita usada para calcular as funções trigonométricas.

Alexander - Restabelecer Monica
fonte