2015-03-25 3 views
8

Я заметил, что M_PI недоступно на c11. Глядя на /usr/include/math.h я могу видеть M_PI определяется, если:M_PI недоступно с gcc -std = c11, но с -std = gnu11?

#if !defined(__STRICT_ANSI__) || ((_XOPEN_SOURCE - 0) >= 500) 
... 
#define M_PI 3.1415... 
#endif 

Кроме того, в math.h из glibc__STRICT_ANSI__ заменяется __USE_MISC. Я полностью потерял это.

Какова история между --std=c11 и константами, определенными в math.h?

Какой libc следует учитывать при распределении debian?

Кстати, M_PI определяется в c99 и gnu11 ...

+0

Почему у вас есть тег C++ 11, если то, что вы просите, явно о C11, а не C++ 11? – juhist

+2

Да, есть, и ваше сообщение уже было отредактировано, чтобы иметь тег c11 вместо C++ 11. – juhist

ответ

11

Это просто: M_PI не определено в стандарте C. Укажите свое собственное определение, если вы хотите быть совместимым со стандартами.

Компиляторы 0 не могут ввести такие константы без нарушения законных программ на С (имя не зарезервировано и может использоваться как идентификатор), и поэтому они определяются только как расширение.

GCC 4.9 when used with -std=c99 doesn't define M_PI, но does when used with -std=gnu99

+0

Однако он был определен в 'c99'. – nowox

+2

@coin Не должно быть - C99 также не определяет 'M_PI'. – milleniumbug

+0

проклятый, я проигнорировал, что я всегда думал, что C99 был стандартом по умолчанию для gcc. Так что же тогда? – nowox

3

M_PI макрос не определяется стандартом C11: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

Поэтому #if охранники защищают вас от проблем в случае, если вы хотите определить свой собственный M_PI макрос. gcc делает именно то, что нужно. Стандартные заголовки не должны произвольно определять макросы, которые не соответствуют стандарту.

4

Если вы просто хотите M_PI в поисках более полного ответа с POSIX/XOpen особенность тестов макросов и т.д., временное решение является:

#ifndef M_PI 
#define M_PI (3.14159265358979323846) 
#endif 

Это формат «1,20», который также является достаточным для представление «round-trip» для 80-разрядного расширенного типа. двойная точность - «1,16». Для точности в 128-битных четырехточиях:

#define M_PI (3.14159265358979323846264338327950288) 

Формат «1.35» для точности округления. Это означает, что если вы хотите распечатать двойной символ с плавающей запятой и восстановить то же значение при его чтении, вы должны использовать «% + 1.16» для функций printf, как и так далее. Вы можете сказать, что double не имеет 17 значащих цифр, но эти цифры не являются «мусорными», если вы хотите восстановить значение.

В любом случае - есть лучшие ресурсы, чем это available.

+0

Для правильного 1.16 -> +1. BTW: Посмотрите на недостатки, чтобы иметь много цифр PI, например, 80 цифр? – chux

+1

@chux - не то, что я могу придумать. gcc, по крайней мере, включает библиотеки gmp/mpfr/mpc, чтобы заботиться обо всех проблемах с множественной точностью, с правильными (и выбираемыми) режимами округления и т. д. Если 80-значное значение PI было назначено для одного прецизионного поплавка, я бы ожидал, делать правильные вещи. Не знаю, насколько обновлена ​​страница [this] (https://gcc.gnu.org/wiki/FloatingPointMath). Я не знаю подхода Кланга. –

 Смежные вопросы

  • Нет связанных вопросов^_^