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

8

Как вы, возможно, знаете, Spotlight может выполнять простую математику. Например, ввод cos(pi)приведет -1, как вы могли ожидать. Я просто набрал cos(pi/2), который должен быть 0, но это дало мне -5e-12.

Да, это, вероятно, из-за ошибки округления, но давай cos(pi/2):! На мой взгляд, это явно похоже на ошибку. Что вы думаете?

poitroae
источник
1
cos (x) - трансцендентная функция. Если они не содержат жестких значений для pi, pi / 2 и т. Д., Следует ожидать некоторой ошибки.
Навин
@ Навин, на самом деле я ожидаю, что они жестко закодируют эти значения, так как они очень важны.
poitroae
1
piсамо по себе будет жестко закодировано (как вы получите -1 для cos(pi)), но как только вы манипулируете им, вы получите число с плавающей запятой, которое имеет ограниченную точность. OSX не жестко программирует pi/2и pi/4т. Д., Фактически выполняет операцию.
Harryg
2
@harryg Хотя есть ошибки округления, которые можно устранить, переключившись на десятичное число, это не одна из них. Десятичная полезна, если вы хотите 0.1точно представить . точно, но это бесполезно для иррациональных чисел, таких как пи, которые не могут быть представлены точно ни в двоичном, ни в десятичном виде.
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
Это, вероятно, больше нехватка точности со значением пи.
Матье Риглер,
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

У меня есть калькулятор TI, который отображает на одну цифру меньше и рассчитывается cos(π/2)как -5.2e-12. Тем не менее, он сильно отличается в электронном виде и был разработан, чтобы дать точное значение для cos(90°).

Я бы предположил, что в Spotlight cos(pi/2)вычисляется путем извлечения значения для π, преобразования в десятичную строку , сохранения его в качестве (точного, рационального) двоичного значения 11.00100100001111110110101010001000100100001101101111 (или 10000), деления на 2 и последующего вычитания этого значения из истинное значение П / 2. Вы должны выяснить, cos(pi/2 + cos(pi/2))ближе ли это к нулю (это может быть -2.2e-35).

Умножение на степень двойки должно влиять только на показатель степени, а не на значение. Может быть возможно определить, как применяется округление путем повторного деления пополам или удвоения.

user130144
источник
В Markdown нет ничего плохого - MathJax включается только на сайтах, связанных с Math, а не в SE.
grg
1
cos (pi / 2 + cos (pi / 2)) отображается как 0 точно.
Ник Маттео
4

Это ошибка, которая воспроизводима в 10.9.2 - и ошибка округления с плавающей запятой, подобная этой, довольно типична.

Это значение пи, которое обрабатывается без достаточной точности, если я должен был угадать.

  • cos (999999 * pi) не имеет ошибки
  • cos ((999999 + 1) * pi) действительно имеет ошибку - вероятное округление

Я бы отправился на https://developer.apple.com/bug-reporting/, если вы хотите увидеть устройство исправления ошибок Apple в действии.

bmike
источник
5
Это ошибка, правда? Какой должна быть точность при такой операции?
Эдуард
Я не зарегистрированный разработчик, но я был бы очень признателен, если бы вы могли представить его нам!
poitroae
4
@ Édouard Вы можете считать это ошибкой, если пользователя ожидают некоторые возможности символической математики. Любая система компьютерной алгебры (CAS), конечно, будет знать, что cos (π / 2) = 0 точно! С другой стороны, вряд ли разумно ожидать, что Spotlight будет содержать CAS. А в области арифметики с плавающей точкой следует ожидать таких результатов, как отчеты OP. Возможно, любой отчет об ошибке лучше обозначить как запрос функции.
Харальд Ханче-Олсен
1
@ Édouard bmike действительно прав, что это ошибка, а не просто ошибка округления. Ожидаемая точность такой операции, учитывая стандартную арифметику двойной точности, составляет около 10 ^ -16, а не 10 ^ -12. Вы можете попробовать это самостоятельно, написав программу на своем любимом языке, которая использует поддержку процессора с плавающей запятой, выполняет вычисления и анализирует битовую комбинацию результата. Как говорит bmike, вероятная причина в том, что значение π, которое использует Spotlight, не определено с достаточной точностью.
Сабольч
2
Здесь происходит что-то странное. cos(2*acos(0)*0.5)возвращает номер заказа 10^-10. Так что это не потому, что константа π недостаточно точна. Я не могу объяснить этот результат: он слишком неточен для двойной точности и слишком точен для одинарной точности.
Сабольч
4

Из других ответов и комментариев становится ясно следующее:

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

Это НЕ вина в неточности чисел с плавающей запятой. Результат, который вы получите, это:

cos(1.5707963268)

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

В заключение я вижу два возможных ограничения, одно из которых должно применяться:

  1. Pi не сохраняется с достаточной точностью, или, по крайней мере, pi / 2 приводит к недостаточной точности
  2. Cos просто принимает недостаточную точность в качестве входных данных

Возможно, кто-то, имеющий доступ к программному обеспечению, может проверить, какое из этих применений применимо.

Обновление Как уже упоминалось в комментарии, проблема заключается в точности константы pi.

Деннис Джаэруддин
источник
Это странно 1.5707963268 - это результат, который Spotlight дает вам при вычислении pi / 2. После нескольких простых попыток кажется, что Spotlight отображает 10 значащих цифр для чисел ниже 1 и 11 для чисел выше 1. Но по какой странной причине реализации будет применяться шаг округления внутри вычисления, а не после?
Эдуар
1
Я также хотел бы отметить, что если вы предоставите Spotlight более точное приближение pi / 2 (например, путем копирования более 10 цифр из Wolfram Alpha), точность возрастет.
Эдуар
Спасибо за подтверждение моего предположения, что точность пи была причиной ошибки между 0 и примерно 10 ^ -12 в вопросе ОП.
bmike
Как часто вы видите это: «10 ^ -12 действительно большой»
GEdgar
2

Учитывая , что -5e-12является verryyyy небольшого числа, это является ошибкой округления.

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

Александр - Восстановить Монику
источник