如何在c99中使用PI [英] how to use PI in c99

查看:66
本文介绍了如何在c99中使用PI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现(搜索n1124.pdf)在c99 math.h

不包含M_PI


什么是那么在交流代码中使用PI常数的方法呢?


#define PI 3.1415926535897932384626433832795

#define PI(4 * atan(1))

....



解决方案

Szabolcs Nagy写道:


我刚刚发现(在n1124.pdf中搜索)在c99 math.h中

不包含M_PI


那么在交流代码中使用PI常数的理想方法是什么?


#define PI 3.1415926535897932384626433832795

#define PI( 4 * atan(1))

...




定义PI的问题是你有至少3种不同的

表示pi:float / double / long double / complex /


什么是最佳代表?

并使用哪种舍入模式?


最好的事情就是自己定义并随意决定你想要将常量作为(比方说)long double。

#define PI 3.1415926535897932384626433832795L

jacob


Szabolcs Nagy写道:
< blockquote class =post_quotes>
>

我刚刚发现(在n1124.pdf中搜索)c99 math.h

不包含M_PI


那么在交流码中使用PI常数的理想方法是什么?


#define PI 3.1415926535897932384626433832795

#define PI(4 * atan(1))

...




除了雅各布的积分,你还应该考虑这个:


你想把PI定义为每次使用时,必须在运行时计算一个常数,或者是
的东西吗?


-

+ ------------------------- + -------------------- + --- -------------------- +

| Kenneth J. Brody | www.hvcomputer.com | #include |

| kenbrody / at\spamcop.net | www.fptech.com | < std_disclaimer.h |

+ ------------------------- + --------- ----------- + ----------------------- +

不要 - 邮寄给我:< mailto:Th ************* @ gmail.com>


Szabolcs Nagy写道:


我刚刚发现(通过n1124.pdf搜索)在c99 math.h中

不包含M_PI


那么在交流代码中使用PI常数的理想方法是什么?


#define PI 3.1415926535897932384626433832795

#定义PI(4 * atan(1))

....




(4 * atan(1))形式有两个明显的缺点

a)atan(1)在编译时不计算时间,所以每次使用PI时都会计算
atan(1)

b)atan()返回一个double。你的第一个表格,其数字比

多,大多数实现都有很长的两倍,这表明你希望获得超过天体物理学要求的精确度。

a。 >
如果LDBL_DIG DBL_DIG你可以找到(4 * atan(1)),那么精确度就越低了



假设你运行这样的程序:


#include< stdio.h>

#include< float.h>

#include< math.h>


#define PI_F 3.1415926535897932384626433832795f

#define PI_D 3.1415926535897932384626433832795

#define PI_L 3.1415926535897932384626433832795l

#define PI_C(4 * atan(1))


int main(无效)

{

printf(" printf PI_x as double:\ n");

printf(" PI_F%。* g\ n",DBL_DIG,PI_F);

printf(" PI_D%。* g\ n",DBL_DIG,PI_D);

printf(" PI_L%。* g\ n",DBL_DIG,( double)PI_L);

printf(" PI_C%。* g\\\
\ n",DBL_DIG,PI_C);

printf(" printf PI_x as long double:\ n");

printf(" PI_F%。* Lg \ n",LDBL_DIG,(long double)PI_F);

printf( PI_D%。* Lg \ n,LDBL_DIG,(长双)PI_D);

printf(PI_L%。* Lg \ n,LDBL_DIG,PI_L);

printf(" PI_C%。* Lg\\\
\ n",LDBL_DIG,(长双)PI_C);


返回0;

}


一个实现的输出

printf PI_x为double:

PI_F 3.14159274101257

PI_D 3.14159265358979

PI_L 3.14159265358979

PI_C 3.14159265358979

printf PI_x长双:

PI_F 3.14159274101257324

PI_D 3.14159265358979312

PI_L 3.14159265358979324

PI_C 3.14159265358979312

建议此实施:

a)如果浮动操作是fa比双打更多,而不是8

需要有效数字

#define PI 3.14159265f

足够

b )如果双重操作至少与浮点数一样快,并且没有超过16位有效数字,或者,无论浮动和双打的相对价格是多少,如果是9但不超过16

需要有效数字

#define PI 3.141592653589793

首选

c)如果使用标准

类型需要最大可能的精度,使用

#define PI 3.1415926535897932384626433832795l

是最好的。

事实上,这些定义中的每一个都应该包含所有数字,直到某些不需要的精度水平,因为不同的实现可能会很好地利用
这个实现更多。


我能看到
的唯一原因


#define PI(4 * atan(1 ))



是实现可能确保这具有双倍可以达到的最大精度和准确度(但不会更多)。

但是可能可以用

#define PI 3.1415926535897932384626433832795 / * double * /

更好。

如果你坚持使用(4 * atan) (1))形式,使用,而不是定义,

现在每个函数使用符号PI

const double PI = 4 * atan(1);

对所有上限的标识符采用通常的约定。


i''ve just found out (searching through n1124.pdf) that in c99 math.h
does not contain M_PI

what is the desired way to use the PI constant in a c code then?

#define PI 3.1415926535897932384626433832795
#define PI (4*atan(1))
....
?

解决方案

Szabolcs Nagy wrote:

i''ve just found out (searching through n1124.pdf) that in c99 math.h
does not contain M_PI

what is the desired way to use the PI constant in a c code then?

#define PI 3.1415926535897932384626433832795
#define PI (4*atan(1))
...
?

The problem with defining PI is that you have at least 3 different
representations of pi: float/double/long double/complex/

What would be the best representation?
And using which rounding mode?

The best thing is to define it yourself and arbitrarily decide that you
want the constant as a (say) long double.
#define PI 3.1415926535897932384626433832795L

jacob


Szabolcs Nagy wrote:

>
i''ve just found out (searching through n1124.pdf) that in c99 math.h
does not contain M_PI

what is the desired way to use the PI constant in a c code then?

#define PI 3.1415926535897932384626433832795
#define PI (4*atan(1))
...
?

In addition to Jacob''s points, you should also consider this:

Do you want to define PI as a constant, or as something that
has to be calculated at runtime every time you use it?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don''t e-mail me at: <mailto:Th*************@gmail.com>


Szabolcs Nagy wrote:

i''ve just found out (searching through n1124.pdf) that in c99 math.h
does not contain M_PI

what is the desired way to use the PI constant in a c code then?

#define PI 3.1415926535897932384626433832795
#define PI (4*atan(1))
....
?

There are two obvious disadvantages to the (4*atan(1)) form
a) atan(1) is not computed at compile time, so the computation of
atan(1) occurs each time PI is used
b) atan() returns a double. Your first form, which has more digits than
most implementations have for a long double, suggests an desire for
a degree of accuracy beyond the requirements even of astrophysics.
If LDBL_DIG DBL_DIG you may well find (4*atan(1)) the less
satisfactory in terms of precision.

Suppose you ran a program like this:

#include <stdio.h>
#include <float.h>
#include <math.h>

#define PI_F 3.1415926535897932384626433832795f
#define PI_D 3.1415926535897932384626433832795
#define PI_L 3.1415926535897932384626433832795l
#define PI_C (4*atan(1))

int main(void)
{
printf("printf PI_x as double:\n");
printf("PI_F %.*g\n", DBL_DIG, PI_F);
printf("PI_D %.*g\n", DBL_DIG, PI_D);
printf("PI_L %.*g\n", DBL_DIG, (double) PI_L);
printf("PI_C %.*g\n\n", DBL_DIG, PI_C);
printf("printf PI_x as long double:\n");
printf("PI_F %.*Lg\n", LDBL_DIG, (long double) PI_F);
printf("PI_D %.*Lg\n", LDBL_DIG, (long double) PI_D);
printf("PI_L %.*Lg\n", LDBL_DIG, PI_L);
printf("PI_C %.*Lg\n\n", LDBL_DIG, (long double) PI_C);

return 0;
}

The output for one implementation
printf PI_x as double:
PI_F 3.14159274101257
PI_D 3.14159265358979
PI_L 3.14159265358979
PI_C 3.14159265358979

printf PI_x as long double:
PI_F 3.14159274101257324
PI_D 3.14159265358979312
PI_L 3.14159265358979324
PI_C 3.14159265358979312
suggests for this implementation:
a) if float operations are faster than doubles, and no more 8
significant digits are needed
#define PI 3.14159265f
suffices
b) if double operations are at least as fast as floats, and no
more than 16 significant digits, or, whatever the relative
speed of floats and doubles, if at 9 but not more than 16
significant digits are needed
#define PI 3.141592653589793
is preferred
c) If the maximum possibel precision is required with a standard
type, use
#define PI 3.1415926535897932384626433832795l
is best.

In fact each of those defines should probably carry all the digits up to
some unneeded level of precision, since a different implementation might
well make use of more than does this implementation.

The only reason I can see for

#define PI (4*atan(1))

is that the implementation may well ensure that this has the maximum
precision and accuracy that a double can attain (but no more).
But that can probably be done with
#define PI 3.1415926535897932384626433832795 /* double */
better.
If you insist on using the (4*atan(1)) form, use, rather than a define,
in each function that now uses the symbol PI
const double PI = 4 * atan(1);
Straining the usual conventions on identifiers that are all caps.


这篇关于如何在c99中使用PI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆