Почему math.h определяет pi, pi/2, 2/pi, но не 2 * pi?

Это очень простой вопрос: почему существуют предопределенные константы для pi, pi/2, pi/4, 1/pi и 2/pi, но не для 2 * пи? Есть ли еще одна причина?

Этот вопрос касается не всей дискуссии pi vs tau. Мне интересно, есть ли техническая причина для реализации определенных констант, но не для других. Я могу представить две возможности:

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

Ответы

Ответ 1

Это только моя догадка.

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

[email protected]:~/Codes/ref/glibc/math$ grep PI *.c
s_cacos.c:  __real__ res = (double) M_PI_2 - __real__ y;
s_cacosf.c:  __real__ res = (float) M_PI_2 - __real__ y;
s_cacosh.c:                    ? M_PI - M_PI_4 : M_PI_4)
...
s_clogf.c:      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
s_clogl.c:      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
[email protected]:~/Codes/ref/glibc/math$ 

M_PI, M_PI_2 и M_PI_4 появляются довольно часто, но нет 2.0 * M_PI. Итак, для оригинального вопроса Hanno, я думаю, что MvanGeest прав - 2π просто не так полезен, по крайней мере, при реализации libm.

Теперь о M_PI_2 и M_PI_4, их существование вполне оправдано. Документация библиотеки GNU C предполагает, что "эти константы исходят из стандарта Unix98 и также доступны в 4.4BSD" . В то время компиляторы не были такими умными. Ввод M_PI/4 вместо M_PI_4 может привести к ненужному делению. Хотя современные компиляторы могут оптимизировать это (gcc использует mpfr с 2008 года, поэтому даже округление выполняется правильно), использование числовых констант по-прежнему является более переносимым способом записи высокопроизводительного кода.

Ответ 2

Сложно ли писать 2 * M_PI?

Серьезно, хотя однажды, когда люди, обеспокоенные простыми компиляторами, которые не могли выполнять постоянную фальцовку и разделение, были чрезмерно дорогими, на самом деле имело смысл иметь постоянный PI/2, а не рисковать разделом времени исполнения. В нашем современном мире можно было бы просто определить M_PI и назвать его днем, но другие варианты живут для обратной совместимости.