2015-03-25 3 views
8

Ich bemerkte, M_PI ist nicht verfügbar auf c11. Durch die bei /usr/include/math.h ich auf der Suche M_PI sehen kann, ist definiert, wenn:M_PI nicht verfügbar mit gcc --std = c11 aber mit --std = gnu11?

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

Außerdem im math.h von glibc__STRICT_ANSI__ mit __USE_MISC ersetzt wird. Damit bin ich völlig verloren. Wie lautet die Geschichte zwischen --std=c11 und den in math.h definierten Konstanten?

Welche libc sollte ich auf einer debian Verteilung berücksichtigen?

By the way, ist M_PI in c99 und gnu11 ...

+0

Warum haben Sie die C++ 11-Tag, wenn was Sie fragen, ist eindeutig über C11 und nicht C++ 11? – juhist

+2

Ja, es gibt, und Ihr Beitrag wurde bereits bearbeitet, um das c11-Tag anstelle von C++ 11 zu haben. – juhist

Antwort

11

definiert Es ist ganz einfach: M_PI nicht in Standard C. Geben Sie Ihre eigene Definition definiert ist, wenn Sie kompatible Standard-sein wollen.

C Compiler kann nicht führen solche Konstanten ohne brechen legal C-Programme (der Name ist nicht reserviert, und könnte als ein Bezeichner verwendet werden), und als solche sind sie nur als eine Erweiterung definiert.

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

+0

Es wurde jedoch in 'c99' definiert. – nowox

+2

@coin Es sollte nicht sein - C99 definiert auch nicht 'M_PI'. – milleniumbug

+0

verdammt, ignorierte ich, dass ich immer dachte, C99 war der Standard-Standard für gcc. Also was ist es dann? – nowox

3

Das M_PI Makro wird durch den C11-Standard nicht definiert: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

Daher Sie von den Problemen bei, die #if Wachen schützen Sie Ihr eigenes M_PI Makro definieren möchten. gcc macht genau das Richtige. Die Standardheader sollten nicht willkürlich Makros definieren, die nicht im Standard enthalten sind.

4

Wenn Sie nur M_PI wollen, während für eine umfassendere Antwort mit POSIX/XOPEN Feature Tests Makros suchen, usw., eine Zwischenlösung ist:

#ifndef M_PI 
#define M_PI (3.14159265358979323846) 
#endif 

Die „1,20“ -Format, die auch ausreichend ist, ist "Round-Trip" -Darstellung für einen erweiterten 80-Bit-Typ. doppelte Genauigkeit ist "1,16". Für 128-Bit-Vierfach-Präzision:

#define M_PI (3.14159265358979323846264338327950288) 

Das "1.35" -Format für die Rundlaufgenauigkeit. Das bedeutet, wenn Sie einen Gleitkomma-Double ausgeben und denselben Wert wiederherstellen möchten, sollten Sie "% + 1.16" für printf-Funktionen verwenden. Sie könnten sagen, dass ein Double keine 17 signifikanten Ziffern hat, aber diese Ziffern sind nicht "Junk", wenn Sie einen Wert wiederherstellen wollen.

Wie auch immer - es gibt bessere Ressourcen als diese available.

+0

Für korrekte 1.16 -> +1. BTW: Siehst du einen Nachteil darin, viele PI-Ziffern wie 80 Ziffern zu haben? – chux

+1

@chux - das kann ich mir nicht vorstellen. gcc enthält zumindest die gmp/mpfr/mpc-Bibliotheken, um alle Probleme mit Mehrfachpräzision mit korrekten (und auswählbaren) Rundungsmodi usw. zu behandeln. Wenn ein 80-stelliger PI-Wert einem Float mit einfacher Genauigkeit zugewiesen würde, würde ich dies erwarten um das Richtige zu tun. Ich weiß nicht, wie aktuell [this] (https://gcc.gnu.org/wiki/FloatingPointMath) ist. Ich kenne Clangs Ansatz nicht. –

Verwandte Themen