使用符合 C89 标准的 M_PI

发布于 2024-10-17 07:19:37 字数 252 浏览 1 评论 0原文

我正在使用 C 并尝试访问常量 M_PI (3.14159...)。我已经导入了 math.h 头文件,但 M_PI 常量仍然未定义。通过在 StackOverflow 上的一些搜索,我发现我需要将 #define _USE_MATH_DEFINES 添加到我的代码中(请参阅下面的示例代码)。正常编译时效果很好,但我需要能够使用 std=c89 标志来编译我正在做的工作。

我应该如何从某些 C89 代码访问 M_PI?

I'm using C and trying to get access to the constant M_PI (3.14159...). I have imported the math.h header file, but the M_PI constant was still undefined. Through some searching on StackOverflow I have found that I need to add #define _USE_MATH_DEFINES to my code (see example code below). This works fine when compiling normally, but I need to be able to compile with the std=c89 flag for the work that I'm doing.

How should I access M_PI from some C89 code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终陌 2024-10-24 07:19:37

符合标准的标准库文件 math.h 不仅不需要,而且实际上不得默认定义 M_PI。在这种情况下,“默认”意味着 M_PI 必须只能通过编译器特定的技巧来定义,最常见的是通过使用保留标识符来定义未定义的行为。

只需自己定义常量即可(您可以自由使用名称 M_PI,但如果您希望能够使用非兼容编译器编译代码,则必须首先检查 M_PI code> 尚未定义)。为了方便起见,不要将 M_PI 定义为 pi(的近似值)以外的任何值。

A conforming standard library file math.h is not only not required to, but actually must not define M_PI by default. In this context 'by default' means that M_PI must only get defined through compiler-specific tricks, most often undefined behavior through the use of reserved identifiers.

Just define the constant yourself (you can use the name M_PI freely, but should you want to be able to compile the code with a non-conforming compiler, you must first check that M_PI is not already defined). For convention's sake, do not define M_PI as anything other than (the approximation of) pi.

烟酒忠诚 2024-10-24 07:19:37

我会去

#ifndef M_PI
#    define M_PI 3.14159265358979323846
#endif

I would go for

#ifndef M_PI
#    define M_PI 3.14159265358979323846
#endif
撕心裂肺的伤痛 2024-10-24 07:19:37

M_PI 不是 C 标准所必需的,它只是一个常见的扩展,因此如果您想成为标准,则不应依赖它。但是,您可以轻松地为其定义自己的#define,上次我检查它是一个通用常量,因此没有太多混淆的空间。 <代码>:)

M_PI is not required by the C standard, it's just a common extension, so if you want to be standard you shouldn't rely on it. However, you can easily define your own #define for it, last time I checked it was a universal constant so there's not much space for confusion. :)

德意的啸 2024-10-24 07:19:37

我不明白这里有什么问题; -std=c89 和 _USE_MATH_DEFINES 之间没有不兼容性,一个定义编译器将编译什么语言,另一个定义启用 math.h 的哪些部分。

那些启用的部分并未定义为 ISO C 标准的一部分,但这与不是标准 C 语言不同,语言和库在 C 中是独立的实体。与在自己的标头中定义自己的宏相比,C89 的兼容性较差。

不过,我建议您在命令行上而不是在代码中定义宏:

-std=c89 -D_USE_MATH_DEFINES

如果您遇到未定义 M_PI 的 math.h 实现,那么通过类似地使用命令行定义的宏,无需修改代码即可轻松修复该问题:

-std=c89 -DM_PI=3.14159265358979323846

I fail to see what the problem is here; there is no incompatability between -std=c89 and _USE_MATH_DEFINES, one defines what language the compiler will compile, the other defines what parts of math.h get enabled.

Those parts that are enabled are not defined as part of the ISO C standard library, but that is not the same thing as not being standard C language, language and library are separate entities in C. It is no less C89 compliant than it would be if you had defined your own macros in your own header.

I would however suggest that you define the macro on the command-line rather than in the code:

-std=c89 -D_USE_MATH_DEFINES

If you ever encounter a math.h implementation that does not define M_PI, then that is easily fixed without code modification by similarly using command line defined macros:

-std=c89 -DM_PI=3.14159265358979323846
那些过往 2024-10-24 07:19:37

除了缺少 M_PI 定义之外,还记得以下内容仅定义了 double 常量。

#ifndef M_PI
  #define M_PI 3.141592653589793238462643383279502984
  //           1 23456789 123456789 123456789 1234567
#endif

尽管代码中的 3.14159... 适合大约 113 位,但精度通常会变为 53 位,因为它是一个 double 常量。

这对于long double对象和数学来说非常重要。

声明long double常量时请务必使用L

#include <math.h>
#include <stdio.h>
#ifndef M_PI
  #define M_PI 3.141592653589793238462643383279502984
#endif
#define M_PI_L 3.141592653589793238462643383279502984L

#define T(s) #s
#define S(s) T(s)

int main() {
  printf("acos(-1):             %.*g\n", DBL_DECIMAL_DIG, acos(-1));
  printf("M_PI(string):         %s\n", S(M_PI));
  printf("M_PI(double):         %.*g\n", DBL_DECIMAL_DIG, M_PI);
  printf("M_PI(long double):    %.*Lg\n", LDBL_DECIMAL_DIG, (long double) M_PI);
  printf("acosl(-1):            %.*Lg\n", LDBL_DECIMAL_DIG, acosl(-1));
  printf("M_PI_L(string):       %s\n", S(M_PI_L));
  printf("M_PI_L(long double):  %.*Lg\n", LDBL_DECIMAL_DIG, M_PI_L);
}

示例输出:

acos(-1):             3.1415926535897931
M_PI(string):         3.1415926535897932384626433832795
M_PI(double):         3.1415926535897931
M_PI(long double):    3.141592653589793116
acosl(-1):            3.14159265358979323851
M_PI_L(string):       3.141592653589793238462643383279502984L
M_PI_L(long double):  3.14159265358979323851

In addition to M_PI definition missing, recall that the following only defines a double constant.

#ifndef M_PI
  #define M_PI 3.141592653589793238462643383279502984
  //           1 23456789 123456789 123456789 1234567
#endif

Even though the 3.14159... in code is good for about 113-bits, the precision typically becomes 53-bit as it is a double constant.

This can be quite important for long double objects and math.

Be sure to use L when declaring a long double constant

#include <math.h>
#include <stdio.h>
#ifndef M_PI
  #define M_PI 3.141592653589793238462643383279502984
#endif
#define M_PI_L 3.141592653589793238462643383279502984L

#define T(s) #s
#define S(s) T(s)

int main() {
  printf("acos(-1):             %.*g\n", DBL_DECIMAL_DIG, acos(-1));
  printf("M_PI(string):         %s\n", S(M_PI));
  printf("M_PI(double):         %.*g\n", DBL_DECIMAL_DIG, M_PI);
  printf("M_PI(long double):    %.*Lg\n", LDBL_DECIMAL_DIG, (long double) M_PI);
  printf("acosl(-1):            %.*Lg\n", LDBL_DECIMAL_DIG, acosl(-1));
  printf("M_PI_L(string):       %s\n", S(M_PI_L));
  printf("M_PI_L(long double):  %.*Lg\n", LDBL_DECIMAL_DIG, M_PI_L);
}

Sample output:

acos(-1):             3.1415926535897931
M_PI(string):         3.1415926535897932384626433832795
M_PI(double):         3.1415926535897931
M_PI(long double):    3.141592653589793116
acosl(-1):            3.14159265358979323851
M_PI_L(string):       3.141592653589793238462643383279502984L
M_PI_L(long double):  3.14159265358979323851
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文