Чому прожектор дає неправильне значення для `cos (pi / 2)`?


8

Як ви можете знати, Spotlight може робити просту математику. Наприклад, введення тексту cos(pi)призведе до того -1, як ви могли очікувати. Я щойно набрав cos(pi/2), що має бути 0, але це дало мені -5e-12.

Так, це, мабуть, пов’язано з помилкою округлення, але давай cos(pi/2):! На мою думку, це явно схоже на помилку. Як ти гадаєш?


1
cos (x) - це трансцендентна функція. Якщо вони не мають значення жорсткого коду для pi, pi / 2 тощо, слід очікувати певної помилки.
Навін

@Navin насправді я очікую, що вони важко кодують ці значення, оскільки вони дуже важливі.
poitroae

1
piСам би був жорстким кодом (як ви отримаєте -1 за cos(pi)), але як тільки ви маніпулюєте ним, ви отримуєте число з плаваючою комою, що має обмежену точність. OSX не описує pi/2, і pi/4т.д., він фактично робить операцію.
харриг

2
@harryg Хоча є помилки округлення, які можна вирішити, перейшовши на десятковий, це не одна з них. Десяткові знаки корисні, якщо ви хочете 0.1точно представити . точно, але це не корисно для ірраціональних чисел, таких як pi, які не можуть бути точно представлені ні двійковим, ні десятковим.
CodesInChaos

1
Для довідки, у Ruby:irb(main):009:0> Math.cos(Math::PI/2) => 6.123233995736766e-17
harryg

Відповіді:


13

Це пов'язано з недостатньою точністю пі та через загальну всю недостатню точність вбудованої системи.

pi = 3.1415926536

pi/2 = 1.5707963268 

cos(1.5707963268) = -5.103412e-12

FYI =  5.103412e-12 = 0.000000000005103412 ~ 0 


Про загальну точність системи:

3.141592653589793238462643383 = 3.1415926536 

У Python ми отримуємо наступне:

>>> float("3.141592653589793238462643383")
3.141592653589793

Як ми бачимо, існує проблема з точністю, оскільки вона навіть не відповідає плаваючому уявленню.


Це пов'язано з недостатньою точністю, але помилку такої величини не можна звинувачувати у числах з плаваючою комою.
Денніс Джахеруддін

2
Це, мабуть, більше недостатня точність зі значенням pi.
Матьє Ріглер

5

Вони не зберігають π з незвичною точністю з плаваючою комою. Вони використовують неправильне значення для π з подвійною точністю. Для наближення до 3.1415926536 у двійковій формі потрібно щонайменше 38 біт:

3.14159265359922… > 11.001001000011111101101010100010001001

Зауважте, що 2 ^ -36 - це приблизно 1,5e-11, що збігається з кінцевим 99. Плаваюча точка з подвійною точністю має 52-бітове значення. Оцінити cos(pi/2)як -5e-12, єдиним іншим можливим вибором буде 48-бітний тип, що було б дуже дивно.

Близько 0 і π, де похідна майже дорівнює нулю, cos (θ) не може бути обчислена дуже точно:

cos(3.1415926536) ≈ -0.999999999999999999999947911

Це відрізняється від -1 приблизно на 5.2e-23, що менше ε для double, тому cos(3.1415926536)обчислюється як саме -1 ... що невірно.

Близько ± π / 2, похідна [ -sin (θ) ] майже ± 1, тому помилка на вході стає вихідною.

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

У мене cos(π/2), здається, є калькулятор TI, який відображає одну меншу цифру і обчислює як -5,2e-12. Однак він дуже різний в електронному вигляді і був розроблений, щоб дати точне значення для cos(90°).

Я б припустив, що в Spotlight cos(pi/2)обчислюється шляхом отримання значення для π, перетворення в десятковий рядок , зберігаючи його як (точне, раціональне) двійкове значення 11.00100100001111110110101010001000100100101101111 (або 10000), діливши на 2, а по суті віднімаючи це від справжнє значення П / 2. Ви повинні з’ясувати, чи cos(pi/2 + cos(pi/2))ближче до нуля (це може бути -2,2е-35).

Множення на силу двох повинно впливати лише на показник, а не на значенняі. Можна визначити, як застосовується округлення шляхом повторного скорочення вдвічі або подвоєння.


З Markdown нічого поганого - MathJax увімкнено лише на веб-сайтах, пов'язаних з математикою, а не на широкому рівні.
гр

1
cos (pi / 2 + cos (pi / 2)) відображається як 0 точно.
Нік Маттео

4

Це помилка, яку можна відтворити 10.9.2 - і помилка округлення плаваючої точки, така, яка є досить типовою.

Це значення pi, яке обробляється без достатньої точності, якщо мені доведеться здогадуватися.

  • cos (999999 * pi) не має помилки
  • cos ((999999 + 1) * pi) має помилку - ймовірне округлення

Я б попрямував до https://developer.apple.com/bug-reporting/, якщо ви хочете побачити, що в апараті Apple виправляють помилки.


5
Це справді помилка? Яка повинна бути точність на такій операції?
Édouard

Я не зареєстрований розробник, але буду дуже вдячний, якщо ви можете надіслати його нам!
poitroae

4
@ Edouard Ви могли б розглянути це помилка , якщо користувач був заведений очікувати деякі можливості для символьної математики. Будь-яка комп'ютерна алгебра (CAS), звичайно, знатиме, що cos (π / 2) = 0 точно! З іншого боку, навряд чи можна очікувати, що Spotlight містить CAS. І в царині арифметики з плаваючою комою слід очікувати таких результатів, як звіти про ОП. Будь-який звіт про помилку, можливо, краще буде позначено запитом щодо функції.
Харальд Ханш-Ольсен

1
@ Édouard bmike насправді вірно, що це помилка, а не просто помилка заокруглення. Очікувана точність такої операції з урахуванням арифметики стандартної подвійної точності становить приблизно 10 ^ -16, а не 10 ^ -12. Ви можете спробувати це самостійно, написавши програму на своїй улюбленій мові, яка використовує перевагу підтримки CPU з плаваючою точкою, зробивши обчислення та вивчивши біт-шаблон результату. Як говорить bmike, ймовірною причиною є те, що значення π, яке використовує Spotlight, не визначається з достатньою точністю.
Сабольч

2
Тут відбувається щось дивне. cos(2*acos(0)*0.5)повертає ряд замовлень 10^-10. Так це не тому, що константа π недостатньо точна. Я не можу пояснити цей результат: він надто неточний для подвійної точності і занадто точний для одноточної точності.
Szabolcs

4

З інших відповідей та коментарів стає зрозумілим наступне:

Справа в тому, що ви отримуєте ненульовий результат - НЕ помилка, навіть із ідеальною реалізацією програмного забезпечення ви натрапите на межі обчислень з плаваючою комою. Однак похибка порядку 10 ^ -12 дійсно велика.

Це НЕ винен у неточності чисел з плаваючою комою. Результат, який ви отримуєте, саме такий:

cos(1.5707963268)

Це можна перевірити, використовуючи будь-який альтернативний пакет програм. Якщо ви оцінювали cos(pi/2)в одному з цих пакетів, ви неодмінно отримаєте результат набагато ближче до нуля, ніж 10 ^ -12.

На закінчення я бачу два можливі обмеження, одне з яких має застосовуватися:

  1. Pi не зберігається з достатньою точністю, або принаймні pi / 2 призводить до недостатньої точності
  2. Cos просто приймає недостатню точність як вхід

Можливо, хтось із доступом до програмного забезпечення може перевірити, що з них застосовується.

Оновлення Як було сказано в коментарі, проблема здається в точності константи pi.


Це дивно. 1.5707963268 - це результат, який дає прожектор при обчисленні пі / 2. Після кількох простих спроб здається, що Spotlight відображає 10 значущих цифр для числа нижче 1 і 11 для чисел вище 1. Але з якої дивної причини реалізації буде застосовано крок округлення всередині обчислення замість після?
Едуар

1
Я також хотів зазначити, що якщо надати прожектору більш точне наближення pi / 2 (шляхом копіювання, вставляючи більше 10 цифр від Wolfram Alpha, наприклад), точність збільшується.
Едуар

Дякуємо, що підтвердили мою здогадку, що точність pi стала причиною помилки між 0 і приблизно 10 ^ -12 у питанні ОП.
bmike

Як часто ви бачите це: "10 ^ -12 дійсно великий"
GEdgar

2

З огляду на , що -5e-12є verryyyy невеликого числа, це є помилкою округлення.

Я думаю, що це наслідок того, що прожектор показує більше десяткових знаків, ніж використовується для визначення piконстанти або нескінченного ряду, що використовується для обчислення триггерних функцій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.