Spotlight neden `` cos (pi / 2) '' için yanlış bir değer veriyor?


8

Bildiğiniz gibi Spotlight basit matematik yapabilir. Örneğin, yazmanız beklediğiniz gibi cos(pi)sonuçlanacaktır -1. Yeni yazdım cos(pi/2), 0 olması gerekiyordu ama bana verdi -5e-12.

Evet nedeniyle bir yuvarlama hata olabilir ama hadi: cos(pi/2)! Bence, bu açıkça hataya benziyor. Ne düşünüyorsun?


1
cos (x) aşkın bir fonksiyondur. Pi, pi / 2, vb. İçin sabit kod değerleri olmadıkça, bazı hatalar beklemelisiniz.
Navin

@Navin aslında çok önemli oldukları için bu değerleri sabit kodlamalarını bekliyorum.
14'te poitroae

1
pikendisi sabit kodlanmış olacaktır (-1 elde ettiğinizde cos(pi)), ancak manipüle ettiğiniz anda, sınırlı hassasiyete sahip bir kayan nokta numarası alırsınız. OSX sabit kodlama yapmaz pi/2, pi/4vb.
harryg

2
@harryg Ondalık sayıya geçilerek çözülebilen yuvarlama hataları olsa da, bunlardan biri değil. 0.1Tam olarak temsil etmek istiyorsanız Ondalık yararlıdır . tam olarak, ancak tam olarak ikili veya ondalık olarak gösterilemeyen pi gibi irrasyonel sayılar için yararlı değildir.
CodesInChaos

1
Referans için, Ruby'de:irb(main):009:0> Math.cos(Math::PI/2) => 6.123233995736766e-17
harryg

Yanıtlar:


13

Pi hassasiyetinin eksikliğinden ve dahili sistemdeki genel hassasiyet eksikliğinden kaynaklanmaktadır.

pi = 3.1415926536

pi/2 = 1.5707963268 

cos(1.5707963268) = -5.103412e-12

FYI =  5.103412e-12 = 0.000000000005103412 ~ 0 


Genel sistem hassasiyeti hakkında:

3.141592653589793238462643383 = 3.1415926536 

Python'da aşağıdakileri elde ederiz:

>>> float("3.141592653589793238462643383")
3.141592653589793

Gördüğümüz gibi, şamandıra temsiliyle eşleşmediği için hassasiyette bir sorun var.


Hassasiyet eksikliğinden kaynaklanmaktadır, ancak bu büyüklükteki bir hata kayan nokta sayılarında suçlanamaz.
Dennis Jaheruddin

2
Muhtemelen pi değeri ile daha fazla hassasiyet eksikliği.
Matthieu Riegler

5

Alışılmadık kayan nokta hassasiyetiyle π saklamazlar. Çift hassasiyetli π için yanlış bir değer kullanıyorlar. To yaklaşır ikili 3.1415926536, en az 38 bit gereklidir:

3.14159265359922… > 11.001001000011111101101010100010001001

2 ^ -36'nın yaklaşık 1.5e-11 olduğuna dikkat edin, bu da arkadaki 99 ile çakışır. Çift kesinlikli kayar nokta 52 bitlik bir öneme sahiptir. cos(pi/2)-5e-12 olarak değerlendirmek için , diğer tek seçenek 48 bitlik bir tip olacaktır ve bu çok garip olacaktır.

Türevin neredeyse sıfır olduğu 0 ve π yakınında, cos (θ) çok doğru bir şekilde hesaplanamaz:

cos(3.1415926536) ≈ -0.999999999999999999999947911

Bu -1 ile 5.2e-23 arasında değişir, bu da ε'dan daha küçüktür double, bu yüzden tam olarak -1 ... cos(3.1415926536)olarak hesaplanır, bu da yanlıştır.

± π / 2 yakınında, [ -sin (θ) ] türevi yaklaşık ± 1'dir, bu nedenle girişteki hata çıktı olur.

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

Daha az basamak görüntüleyen ve cos(π/2)-5.2e-12 olarak hesaplayan bir TI hesap makinem var. Bununla birlikte, elektronik olarak çok farklıdır ve kesin bir değer vermek için tasarlanmıştır cos(90°).

Spotlight'ta, cos(pi/2)π için bir değer alınarak, ondalık bir dizeye dönüştürülerek , (tam, rasyonel) ikili değer olarak 11.00100100001111110110101010001000100100001101101111 (veya 10000) olarak depolanarak, 2'ye bölünerek ve temelde gerçek değer tt / 2. cos(pi/2 + cos(pi/2))Sıfıra daha yakın olup olmadığını öğrenmelisiniz (-2.2e-35 olabilir).

İki güçle çarpma, anlamlılığı değil, sadece üssü etkilemelidir. Tekrarlanan yarıya ya da iki katına çıkarak yuvarlamanın nasıl uygulanacağını belirlemek mümkün olabilir.


Markdown ile ilgili bir sorun yok - MathJax, SE ile değil, yalnızca Math ile ilgili sitelerde etkinleştirilir.
grg

1
cos (pi / 2 + cos (pi / 2)) tam olarak 0 olarak görüntülenir.
Nick Matteo

4

Bu, 10.9.2'de tekrarlanabilir bir hatadır - ve bunun gibi bir kayan nokta yuvarlama hatası oldukça tipiktir.

Tahmin etmem gerekirse, yeterince hassas olmadan işlenen pi'nin değeri.

  • cos (999999 * pi) bir hata yok
  • cos ((999999 + 1) * pi) bir hata var - büyük olasılıkla yuvarlama

Apple'ın hata düzeltme aparatını çalışırken görmek istiyorsanız https://developer.apple.com/bug-reporting/ adresine giderim .


5
Gerçekten bir böcek mi? Böyle bir operasyonda hassasiyet ne olmalıdır?
Édouard

Kayıtlı bir geliştirici değilim, ama bizim için gönderebilirseniz çok minnettar olurum!
14'te poitroae

4
Édouard @ Sen olabilir kullanıcı sembolik matematik için bazı yetenekler beklemek neden olup olmadığını o bir hata düşünün. Herhangi bir bilgisayar cebir sistemi (CAS) elbette cos (π / 2) = 0 tam olarak bilir! Öte yandan, Spotlight'ın CAS içermesini beklemek neredeyse mantıklı değil. Kayan nokta aritmetiği alanında, OP raporları gibi sonuçlar beklenmelidir. Herhangi bir hata raporu, belki de bir özellik isteği olarak daha iyi etiketlenebilir.
Harald Hanche-Olsen

1
@ Édouard bmike aslında bunun sadece bir hata değil , bir hata olduğu doğrudur . Standart çift kesinlikli aritmetik verildiğinde böyle bir işlemin beklenen hassasiyeti 10 ^ -12 değil, yaklaşık 10 ^ -16'dır. CPU'nun kayan nokta desteğinden yararlanan, hesaplamayı yaparak ve sonucun bit desenini inceleyerek en sevdiğiniz dilde bir program yazarak bunu kendiniz deneyebilirsiniz. Bmike'ın dediği gibi, olası neden Spotlight'ın kullandığı π değerinin yeterli hassasiyetle tanımlanmamış olmasıdır.
Szabolcs

2
Burada tuhaf bir şeyler oluyor. cos(2*acos(0)*0.5)bir dizi sipariş döndürür 10^-10. Yani π sabiti yeterince kesin olmadığı için değil. Bu sonucu açıklayamıyorum: çift kesinlik için çok kesin değil ve tek kesinlik için çok hassas.
Szabolcs

4

Diğer cevap ve yorumlardan aşağıdakiler netleşir:

Sıfır olmayan bir sonuç almanız gerçeği bir hata DEĞİLDİR, yazılımın mükemmel bir uygulamasıyla bile kayan nokta hesaplamalarının sınırlarına girersiniz. Ancak, 10 ^ -12 sırasıyla hata gerçekten büyük.

Bu, kayan nokta sayılarının yanlışlığını suçlamak DEĞİLDİR. Elde ettiğiniz sonuç şudur:

cos(1.5707963268)

Bu, herhangi bir alternatif yazılım paketi kullanılarak doğrulanabilir. Eğer cos(pi/2)bu paketlerden birinde değerlendirecek olsaydınız, kesinlikle sıfıra 10 ^ -12'den çok daha yakın bir sonuç elde edersiniz.

Sonuç olarak, biri geçerli olmak üzere iki olası sınırlama görüyorum:

  1. Pi yeterli hassasiyetle depolanmaz veya en azından pi / 2 yetersiz hassasiyetle sonuçlanır
  2. Cos sadece girdi olarak yetersiz hassasiyet alır

Belki de yazılıma erişimi olan biri bunlardan hangisinin geçerli olduğunu doğrulayabilir.

Güncelleme Yorumda belirtildiği gibi, sorun sabitin doğruluğu gibi görünüyor pi.


Bu çok garip. 1.5707963268 pi / 2 hesapladığınızda Spotlight'ın size verdiği sonuçtur. Yuvarlama aşaması uygulanacak Garip olan ne uygulama nedeni, birkaç basit denemeden sonra, Spotlight ekranlar gibi 10 önemli 1'in altına sayısı için rakam ve 1. Yukarıdaki Ama için numaralar için 11 görünüyor hesaplama yerine sonra?
Édouard

1
Ayrıca Spotlight'a daha hassas bir pi / 2 (Wolfram Alpha'dan 10'dan fazla basamak kopyalayarak yapıştırarak) sağlarsanız, hassasiyetin arttığını belirtmek istedim.
Édouard

OP sorusunda pi'nin hassasiyetinin 0 ile kabaca 10 ^ -12 arasındaki hatanın nedeni olduğunu tahmin ettiğim için teşekkürler.
bmike

Bunu ne sıklıkta görüyorsunuz: "10 ^ -12 gerçekten büyük"
GEdgar

2

Düşünülürse -5e-12bir verryyyy az sayıda olduğu, bu ise bir yuvarlama hatası.

Sanırım bu, pitrig fonksiyonlarını hesaplamak için kullanılan sabit veya sonsuz serilerin tanımında kullanılandan daha fazla ondalık sayı gösteren bir sonucun sonucudur .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.