C中的数学常数PI值

use*_*016 62 c

计算PI值是一个复杂的问题,维基百科谈到了为它做的近似,并说很难准确计算PI.

C如何计算PI?它是每次计算还是使用不太准确的固定值?

gri*_*fos 75

在C中,在math.h中定义: #define M_PI 3.14159265358979323846

  • 不完全 - 事实上,符合C的实现*可能不会在`<math.h>`中定义`PI`.POSIX指定了"M_PI",但同样,符合C的实现可能无法定义它.(POSIX强加了一些与C标准冲突的要求.)但您可以在自己的程序中以这种方式定义它. (31认同)
  • 附加信息:如果您使用M_PI并获取未定义的错误 - 这可以通过#define _USE_MATH_DEFINES解决 (4认同)
  • @Danijel M 代表“数学”。过去,所有“数学常数”都以“M_”为前缀。还有像`M_E`、`M_LN10`等。他们从来没有达到标准。 (3认同)
  • 并且该值是双精度值可用的最准确表示. (2认同)
  • 所以它是固定值,不可能有更高的精度? (2认同)

R..*_*R.. 24

C以对应用程序直接可见的方式"计算π"所做的最接近的事情是acos(-1)或类似的.对于所计算的函数(在C中或由FPU微码),这几乎总是用多项式/有理近似来完成.

然而,一个有趣的问题是,计算三角函数(sin,cos,和tan)要求减少他们的说法模为2π的.由于2π不是二元有理(甚至不理性),它不能用任何浮点类型表示,因此使用该值的任何近似将导致大参数的灾难性错误累积(例如,如果x1e12,并且2*M_PI不同于2π通过ε,则fmod(x,2*M_PI)与正确的2π值相差最多1e12*ε/π乘以xmod2π 的正确值.也就是说,它完全没有意义.

C语言标准数学库的正确实现只是在其源代码中有一个巨大的非常高精度的π硬编码表示,以处理正确的参数减少问题(并使用一些花哨的技巧使其不那么巨大).这就是sin/ cos/ tan函数的大多数/所有C版本的工作方式.但是,某些实现(如glibc)已知在某些cpus(如x86)上使用程序集实现,并且不执行正确的参数减少,从而导致完全无意义的输出.(顺便提一下,不正确的asm通常与小参数的正确C代码运行速度大致相同.)

  • 我正在寻找 ISO C,附件 F,三角函数的参考,但显然没有硬性要求它们是 IEEE 三角函数(这将要求它们对于所有输入都是正确的,并且正确四舍五入)。因此,与其说是正确性,不如说是 QoI(实施质量)问题。但是基于 fdlibm 的实现具有在整个可表示值域中工作的参数缩减。 (2认同)
  • @Fritz:根据我的回答中的粗略分析,`fmod(x,2*M_PI)` 与正确的参数减少值的误差在 `x` 的量级上线性增长。因此,假设单位圆外的 `x` 为 1ulp,你会看到类似 1000ulp 的`1000*M_PI`。在零点附近,sin 接近线性,斜率为 1,因此参数中的 ulp 的 # 直接转换为结果中的 ulp。 (2认同)

Mar*_*vič 20

只需定义:

#define M_PI acos(-1.0)
Run Code Online (Sandbox Code Playgroud)

它应该为您提供数学函数正在使用的精确PI编号.因此,如果他们改变PI值,他们正在使用正切或余弦或正弦,那么您的程序应该始终是最新的;)

  • 每次使用常数时,这将评估相当昂贵的功能(acos).几乎没有一种有效而合理的方法. (4认同)
  • @JaromírAdamec实际上,任何好的编译器都应该将该表达式优化为常量,而acos是来自使用常量参数调用的标准库的纯函数; 除非你关闭优化编译,否则就是这样. (3认同)
  • @JaromírAdamec 相反,*C 标准明确允许 - 甚至认可 - 编译器知道所有标准库函数的复杂细节! (2认同)

Maz*_*ani 7

无论如何,你没有无限的准确性,所以C用这种方式定义一个常数:

#define PI 3.14159265358979323846
Run Code Online (Sandbox Code Playgroud)

导入math.h来使用它

  • 啊,你在看SUSv2,*不是POSIX*.这是在UNIX/POSIX规范合并之前,此时整个SUS是XSI.从SUSv3开始,Unix和POSIX标准合并,XSI选项是Unix的一部分,这些选项被认为对所有POSIX系统都不支持是不够有用或通用的.后来在SUSv4(POSIX 2008)中,一些更有用的XSI选项被转移到基础(POSIX)标准,而那些不太有用的选项逐渐被标记为过时,所以最终运气好的XSI选项将停止存在... (2认同)