2015-03-25 19 views
8

Ho notato che M_PI non è disponibile su c11. Osservando /usr/include/math.h posso vedere M_PI è definito se:M_PI non disponibile con gcc --std = c11 ma con --std = gnu11?

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

Inoltre nel math.h da glibc__STRICT_ANSI__ è sostituito con __USE_MISC. Sono completamente perso con questo.

Qual è la cronologia compresa tra --std=c11 e le costanti definite in math.h?

Quale libc devo considerare su una distribuzione debian?

A proposito, M_PI è definito in c99 e gnu11 ...

+0

Perché hai il tag C++ 11 se quello che chiedi è chiaramente su C11 e non C++ 11? – juhist

+2

Sì, c'è, e il tuo post è stato già modificato per avere il tag c11 invece di C++ 11. – juhist

risposta

11

E 'semplice: M_PI non è definito nello standard C. Fornire la propria definizione, se si vuole essere standard-compliant.

I compilatori C non possono introdurre costanti di questo tipo senza interrompere i programmi legali C (il nome non è riservato e potrebbe essere utilizzato come identificatore) e, in quanto tali, sono definiti solo come un'estensione.

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

+0

Tuttavia è stato definito in 'c99'. – nowox

+2

@coin Non dovrebbe essere - C99 inoltre non definisce 'M_PI'. – milleniumbug

+0

dannato, ho ignorato che ho sempre pensato che C99 fosse lo standard predefinito per gcc. Allora cos'è allora? – nowox

3

Il M_PI macro non è definito dallo standard C11: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

Pertanto, i #if guardie si stanno proteggendo dai problemi nel caso in cui si desidera definire il proprio M_PI macro. gcc sta facendo esattamente la cosa giusta. Le intestazioni standard non dovrebbero definire arbitrariamente macro che non sono nello standard.

4

Se si desidera solo M_PI mentre alla ricerca di una risposta più completa con POSIX/funzioni XOpen funzione test macro, ecc, una soluzione provvisoria è:

#ifndef M_PI 
#define M_PI (3.14159265358979323846) 
#endif 

Questo è formato "1.20", che è anche sufficiente per rappresentazione "round-trip" per un tipo esteso a 80 bit. la doppia precisione è "1,16". Per la precisione quad a 128 bit:

#define M_PI (3.14159265358979323846264338327950288) 

Il formato "1,35" per la precisione di andata e ritorno. Questo significa che se vuoi stampare un double point mobile e recuperare lo stesso valore quando lo rileggi, dovresti usare "% + 1.16" per le funzioni printf, così via. Si potrebbe dire che un doppio non ha 17 cifre significative, ma quelle cifre non sono "spazzatura" se si desidera recuperare un valore.

In ogni caso, ci sono risorse migliori di questo available.

+0

Per correggere 1.16 -> +1. BTW: vedi uno svantaggio di avere molte cifre PI come 80 cifre? – chux

+1

@chux - non che io possa pensare. gcc include almeno le librerie gmp/mpfr/mpc per occuparsi di tutti i problemi di precisione multipla, con modi di arrotondamento corretti (e selezionabili), ecc. Se un valore PI di 80 cifre è stato assegnato a un singolo galleggiante di precisione, mi aspetterei che fare la cosa giusta Non so come sia aggiornata la pagina [this] (https://gcc.gnu.org/wiki/FloatingPointMath). Non conosco l'approccio clang. –

Problemi correlati