Dlaczego Spotlight podaje złą wartość dla `cos (pi / 2)`?


8

Jak być może wiesz, Spotlight potrafi wykonywać proste zadania matematyczne. Na przykład pisanie cos(pi)spowoduje -1, jak można się spodziewać. Właśnie wpisałem cos(pi/2), co powinno być 0, ale dało mi to -5e-12.

Tak, jest to prawdopodobnie ze względu na zaokrąglenia błędów, ale daj spokój: cos(pi/2)! Moim zdaniem to wygląda jak błąd. Co myślisz?


1
cos (x) jest funkcją transcendentalną. O ile nie mają wartości kodu dla pi, pi / 2 itd., Należy spodziewać się błędu.
Navin

@Navin tak naprawdę spodziewam się, że zakodują te wartości na stałe, ponieważ są one bardzo ważne.
poitroae

1
pisam byłby zakodowany na stałe (gdy dostajesz -1 za cos(pi)), ale jak tylko nim manipulujesz, otrzymujesz liczbę zmiennoprzecinkową, która ma ograniczoną precyzję. OSX nie twarde kod pi/2, pi/4etc, to rzeczywiście robi operacja.
harryg

2
@harryg Chociaż występują błędy w zaokrąglaniu, które można rozwiązać przełączając na dziesiętne, nie jest to jeden z nich. Dziesiętny jest przydatny, jeśli chcesz 0.1dokładnie reprezentować . dokładnie, ale nie jest to przydatne w przypadku liczb niewymiernych, takich jak pi, których nie można dokładnie przedstawić w postaci binarnej ani dziesiętnej.
CodesInChaos

1
Dla porównania, w Ruby:irb(main):009:0> Math.cos(Math::PI/2) => 6.123233995736766e-17
harryg

Odpowiedzi:


13

Wynika to z braku precyzji pi oraz z ogólnego braku precyzji we wbudowanym systemie.

pi = 3.1415926536

pi/2 = 1.5707963268 

cos(1.5707963268) = -5.103412e-12

FYI =  5.103412e-12 = 0.000000000005103412 ~ 0 


O ogólnej precyzji systemu:

3.141592653589793238462643383 = 3.1415926536 

W Pythonie otrzymujemy:

>>> float("3.141592653589793238462643383")
3.141592653589793

Jak widzimy, istnieje problem z precyzją, ponieważ nie jest on nawet zgodny z reprezentacją zmiennoprzecinkową.


Wynika to z braku precyzji, ale błędu tej wielkości nie można przypisać liczbom zmiennoprzecinkowym.
Dennis Jaheruddin

2
Prawdopodobnie jest to raczej brak precyzji przy wartości pi.
Matthieu Riegler,

5

Nie przechowują π z niezwykłą precyzją zmiennoprzecinkową. Używają niepoprawnej wartości π z podwójną precyzją. Aby w przybliżeniu 3.1415926536 binarnie, wymagane jest co najmniej 38 bitów:

3.14159265359922… > 11.001001000011111101101010100010001001

Zauważ, że 2 ^ -36 wynosi około 1,5e-11, co pokrywa się z końcową liczbą 99. Zmienna zmiennoprzecinkowa podwójnej precyzji ma znaczenie 52-bitowe. Aby ocenić cos(pi/2)jako -5e-12, jedynym innym możliwym wyborem byłby typ 48-bitowy, co byłoby bardzo dziwne.

Blisko 0 i π, gdzie pochodna wynosi prawie zero, cos (θ) nie może być obliczone bardzo dokładnie:

cos(3.1415926536) ≈ -0.999999999999999999999947911

Różni się to od -1 o około 5,2e-23, co jest mniejsze niż ε dla double, więc cos(3.1415926536)jest obliczane jako dokładnie -1 ... co jest niepoprawne.

W pobliżu ± π / 2 pochodna [ -sin (θ) ] wynosi prawie ± 1, więc błąd na wejściu staje się wyjściem.

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

cos(π/2)Zdarza mi się mieć kalkulator TI, który wyświetla jedną cyfrę mniej i oblicza jako -5,2e-12. Jest jednak zupełnie inny pod względem elektronicznym i został zaprojektowany w celu podania dokładnej wartości cos(90°).

Domyślam się, że w Spotlight cos(pi/2)jest obliczany przez pobranie wartości π, konwersję do ciągu dziesiętnego , przechowywanie go jako (dokładnej, wymiernej) wartości binarnej 11.00100100001111110110101010001000100100001101101111 (lub 10000), dzielenie przez 2, a następnie odejmowanie tego od prawdziwa wartość od p / 2. Powinieneś dowiedzieć się, czy cos(pi/2 + cos(pi/2))jest bliżej zera (może to być -2,2e-35).

Mnożenie przez potęgę dwóch powinno wpływać tylko na wykładnik, a nie na znaczenie. Możliwe jest określenie, w jaki sposób stosuje się zaokrąglanie, poprzez powtarzanie o połowę lub podwojenie.


Z Markdown nie ma nic złego - MathJax jest włączony tylko na stronach związanych z matematyką, a nie w całej SE.
grg

1
cos (pi / 2 + cos (pi / 2)) wyświetla się dokładnie jako 0.
Nick Matteo

4

Jest to błąd, który można odtworzyć w 10.9.2 - a błąd zaokrąglania zmiennoprzecinkowego taki jak ten jest dość typowy.

To wartość pi jest obsługiwana bez wystarczającej precyzji, gdybym musiał zgadywać.

  • cos (999999 * pi) nie ma błędu
  • cos ((999999 + 1) * pi) ma błąd - prawdopodobnie zaokrąglenie

Chciałbym wejść na https://developer.apple.com/bug-reporting/, jeśli chcesz zobaczyć, jak działa aparat naprawiający błędy Apple.


5
Czy to naprawdę błąd? Jaka powinna być precyzja takiej operacji?
Édouard

Nie jestem zarejestrowanym programistą, ale byłbym bardzo wdzięczny, gdybyś mógł nam go przesłać!
poitroae

4
@ Edouard możliwość może rozważyć błąd, jeśli użytkownik został doprowadziły do spodziewać się pewnych zdolności do matematyki symbolicznych. Każdy komputerowy system algebry (CAS) będzie oczywiście wiedział, że cos (π / 2) = 0 dokładnie! Z drugiej strony nie można oczekiwać, że Spotlight będzie zawierać CAS. A w dziedzinie arytmetyki zmiennoprzecinkowej należy spodziewać się wyników takich jak raporty PO. Każdy raport o błędzie może być lepiej oznaczony jako żądanie funkcji.
Harald Hanche-Olsen

1
@ Édouard bmike jest w rzeczywistości poprawny, ponieważ jest to błąd, a nie tylko błąd zaokrąglenia. Oczekiwana precyzja takiej operacji, biorąc pod uwagę standardową arytmetykę podwójnej precyzji, wynosi około 10 ^ -16, a nie 10 ^ -12. Możesz tego spróbować samodzielnie, pisząc program w swoim ulubionym języku, który wykorzystuje obsługę zmiennoprzecinkową procesora, wykonując obliczenia i sprawdzając wzór bitowy wyniku. Jak mówi bmike, prawdopodobnym powodem jest to, że wartość π używana przez Spotlight nie jest zdefiniowana z wystarczającą precyzją.
Szabolcs

2
Dzieje się tu coś dziwnego. cos(2*acos(0)*0.5)zwraca liczbę zamówień 10^-10. Nie dzieje się tak dlatego, że stała π nie jest wystarczająco precyzyjna. Nie potrafię wyjaśnić tego wyniku: jest zbyt nieprecyzyjny dla podwójnej precyzji i zbyt precyzyjny dla pojedynczej precyzji.
Szabolcs

4

Z pozostałych odpowiedzi i komentarzy wynika, że:

Fakt, że otrzymasz niezerowy wynik, NIE jest błędem, nawet przy doskonałej implementacji oprogramowania wpadłbyś w granice obliczeń zmiennoprzecinkowych. Jednak błąd rzędu 10 ^ -12 jest naprawdę duży.

NIE jest to winą niedokładności liczb zmiennoprzecinkowych. Otrzymany wynik jest następujący:

cos(1.5707963268)

Można to sprawdzić za pomocą dowolnego alternatywnego pakietu oprogramowania. Jeśli oceniasz cos(pi/2)w jednym z tych pakietów, na pewno uzyskasz wynik znacznie bliższy zeru niż 10 ^ -12.

Podsumowując, widzę dwa możliwe ograniczenia, z których jedno musi mieć zastosowanie:

  1. Pi nie jest przechowywane z wystarczającą precyzją lub przynajmniej pi / 2 powoduje niedostateczną precyzję
  2. Cos po prostu wymaga niewystarczającej precyzji jako danych wejściowych

Być może ktoś z dostępem do oprogramowania może sprawdzić, które z nich ma zastosowanie.

Aktualizacja Jak wspomniano w komentarzu, problemem wydaje się być dokładność stałej pi.


To dziwne. 1.5707963268 to wynik, jaki daje Spotlight podczas obliczania pi / 2. Po kilku prostych prób, wydaje się, że wyświetlacze Spotlight 10 cyfr znaczących dla liczby poniżej 1 i 11 dla liczb powyżej 1. Ale za to, co dziwne realizacja powód by zaokrąglenia krok być stosowane wewnątrz obliczeń zamiast po?
Édouard,

1
Chciałem również zauważyć, że jeśli zapewnisz Spotlight bardziej precyzyjne przybliżenie pi / 2 (np. Poprzez skopiowanie i wklejenie więcej niż 10 cyfr z Wolfram Alpha), precyzja wzrośnie.
Édouard,

Dzięki za potwierdzenie mojego przypuszczenia, że ​​precyzja pi była przyczyną błędu między 0 a około 10 ^ -12 w pytaniu PO.
bmike

Jak często to widzisz: „10 ^ -12 jest naprawdę duży”
GEdgar

2

Biorąc pod uwagę, że -5e-12jest to bardzo mała liczba, jest to błąd zaokrąglania.

Myślę, że jest to konsekwencja pokazania większej liczby miejsc po przecinku niż w definicji pistałej lub nieskończonej serii użytej do obliczenia funkcji trig.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.