计算PI值是复杂的问题之一,维基百科谈到了 近似值了为此所做处理,并说很难准确计算PI。
C如何计算PI?它是每次计算还是使用不那么精确的固定值?
计算PI值是复杂的问题之一,维基百科谈到了 近似值了为此所做处理,并说很难准确计算PI。
C如何计算PI?它是每次计算还是使用不那么精确的固定值?
Answers:
在C中,Pi在math.h中定义: #define M_PI 3.14159265358979323846
PI
在C中定义一致的C实现<math.h>
。POSIX指定M_PI
,但是同样,符合C的实现可能未定义它。(POSIX提出了一些与C标准冲突的要求。)但是您可以在自己的程序中以这种方式定义它。
M_
。也有一样的东西M_E
,M_LN10
等他们从未做了它对标准。
C对应用程序直接可见的方式与“计算π”最接近的事情是 acos(-1)
或类似。对于要计算的函数(使用C或FPU微代码),几乎总是使用多项式/有理数逼近来完成。
然而,一个有趣的问题是,计算三角函数(sin
,cos
,和tan
)要求减少他们的说法模为2π的。由于2π不是绝对的有理数(甚至不是有理数),因此它不能以任何浮点类型表示,因此使用任何近似值都会导致大自变量的灾难性错误累积(例如,x
is1e12
和2*M_PI
与2π不同乘以ε,则fmod(x,2*M_PI)
与2π的正确值之差最多为mod2π的正确值的1e12 *ε/π倍x
,也就是说,这完全没有意义。
C的标准数学库的正确实现只是在其源代码中包含一个巨大的π硬编码的超高精度表示形式,以处理正确的参数归约问题(并使用一些花哨的技巧使它变得不那么庞大) )。这是大多数/所有C版本的sin
/ cos
/tan
函数的工作方式。但是,已知某些实现(例如glibc)在某些cpus(例如x86)上使用汇编实现,并且未执行正确的参数约简,导致完全无意义的输出。(顺便说一句,不正确的asm通常与小参数的正确C代码以大约相同的速度运行。)
x
几乎是没有意义的,并且很可能是使用正弦函数的代码中的错误。如果x
太大而变成整数,则x
每个正弦周期只能表示6个值。当然,可以找到y
满足条件的a,这很好,但是我怀疑在计算整数的正弦值方面是否有有用的应用。
x
是分析此“ε误差”随着增大的速度x
。如果出现重大错误1000*M_PI
,则表示我理解该问题,并衷心同意您的意见。
fmod(x,2*M_PI)
vs正确的参数减少值的误差随的幅度线性增长x
。因此,假设x
单位圆外刚好为1ulp ,您将为看到类似1000ulp的值1000*M_PI
。零点sin
附近的线性与斜率1接近,因此参数中的ulp数直接转换为结果中的ulp。
sin(2^n)
对于较大的值有有趣的应用n
; 我不记得他们马上要做什么。
只需定义:
#define M_PI acos(-1.0)
它应该为您提供数学函数正在使用的确切PI编号。因此,如果他们更改正切线,余弦或正弦值的PI值,则您的程序应始终保持最新;)
acos
函数是C语言本身的一部分。
无论如何,您都没有无限的精度,因此C可以这样定义一个常数:
#define PI 3.14159265358979323846
导入math.h来使用它
M_PI
不在C中。它是POSIX中XSI扩展选项的一部分。
根据库的不同,您在这里使用标准的GNU C预定义数学常数... https://www.gnu.org/software/libc/manual/html_node/Mathematical-Constants.html
您已经有了它们,为什么还要重新定义它们?您的系统桌面计算器可能具有它们,并且甚至更准确,因此您可以,但是请确保与现有定义的计算器不冲突,以节省编译警告,因为它们倾向于此类默认值。请享用!
我不知道究竟是如何C
计算PI
直接作为我更熟悉的C++
不是C
; 但是,您可以具有预定义的内容C
macro
,const
例如:
#define PI 3.14159265359.....
const float PI = 3.14159265359.....
const double PI = 3.14159265359.....
/* If your machine,os & compiler supports the long double */
const long double PI = 3.14159265359.....
或者您可以使用以下两个公式之一进行计算:
#define M_PI acos(-1.0);
#define M_PI (4.0 * atan(1.0)); // tan(pi/4) = 1 or acos(-1)
恕我直言,我不确定100%,但我认为atan()
比便宜acos()
。
#define CONSTANT numberHere
?
C
很生锈,因为我从事这项工作已经有20年之久了,而且我经常使用它C++
。我本来是C++
从一个角度回答这个问题的...我已经更新了答案以适应这个问题……
double
等于)可以计算出太阳系的直径,其误差小于头发宽度。