Sin 和 Cos 对众所周知的角度给出了意想不到的结果
我确信这是一个非常愚蠢的问题,但是当我将 180 度角传递给 c/c++ 的 cos() 和 sin() 函数时,我似乎收到了不正确的值.我知道它应该是:sin 0.0547 和 cos 0.99但我得到了 3.5897934739308216e-009 的 sin 和 -1.00000 的 cos
I am sure this is a really stupid question, but when I pass an angle of 180 degrees into c/c++'s cos() and sin() functions I appear to receive an incorrect value. I know that it should be: sin of 0.0547 and cos of 0.99 but I get sin of 3.5897934739308216e-009 and cos of -1.00000
我的代码是:
double radians = DegreesToRadians( angle );
double cosValue = cos( radians );
double sinValue = sin( radians );
DegreesToRadians() 是:
DegreesToRadians() is:
double DegreesToRadians( double degrees )
{
return degrees * PI / 180;
}
谢谢你:)
推荐答案
C/C++提供sin(a)
, cos(a)
, tan(a)
等需要 radian 单位而不是 degrees 的参数的函数.double DegreesToRadians(d)
执行 close 的转换,但转换结果是四舍五入的近似值.机器 M_PI
也很接近,但与数学无理 π
的值不同.
C/C++ provides sin(a)
, cos(a)
, tan(a)
, etc. functions that require a parameter with radian units rather than degrees. double DegreesToRadians(d)
performs a conversion that is close but an approximate as the conversion results are rounded. Also machine M_PI
is close, but not the same value as the the mathematical irrational π
.
带有 180
的 OP 代码传递给 DegreesToRadians(d)
然后传递给 sin()/cos()
给出的结果与预期不同由于四舍五入,double()
的精度有限,并且 PI
的值可能较弱.
OP's code with 180
passed to DegreesToRadians(d)
and then to sin()/cos()
gives results that differ than expected due to rounding, finite precision of double()
and possible a weak value for PI
.
一个改进是在调用 trig 函数之前以 degrees 执行参数缩减.下面首先将角度减小到 -45° 到 45° 的范围,然后调用 sin()
.这将确保 sind(90.0*N) 中
..注意:N
的大值 -->-1.0、0.0、1.0sind(360.0*N +/- 30.0)
可能不完全等于 +/-0.5
.需要一些额外的考虑.
An improvement is to perform argument reduction in degrees before calling the trig function. The below reduces the angle first to a -45° to 45° range and then calls sin()
. This will insure that large values of N
in sind(90.0*N) --> -1.0, 0.0, 1.0
. . Note: sind(360.0*N +/- 30.0)
may not exactly equal +/-0.5
. Some additional considerations needed.
#include <math.h>
#include <stdio.h>
static double d2r(double d) {
return (d / 180.0) * ((double) M_PI);
}
double sind(double x) {
if (!isfinite(x)) {
return sin(x);
}
if (x < 0.0) {
return -sind(-x);
}
int quo;
double x90 = remquo(fabs(x), 90.0, &quo);
switch (quo % 4) {
case 0:
// Use * 1.0 to avoid -0.0
return sin(d2r(x90)* 1.0);
case 1:
return cos(d2r(x90));
case 2:
return sin(d2r(-x90) * 1.0);
case 3:
return -cos(d2r(x90));
}
return 0.0;
}
int main(void) {
int i;
for (i = -360; i <= 360; i += 15) {
printf("sin() of %.1f degrees is % .*e
", 1.0 * i, DBL_DECIMAL_DIG - 1,
sin(d2r(i)));
printf("sind() of %.1f degrees is % .*e
", 1.0 * i, DBL_DECIMAL_DIG - 1,
sind(i));
}
return 0;
}
输出
sin() of -360.0 degrees is 2.4492935982947064e-16
sind() of -360.0 degrees is -0.0000000000000000e+00 // Exact
sin() of -345.0 degrees is 2.5881904510252068e-01 // 76-68 = 8 away
// 2.5881904510252076e-01
sind() of -345.0 degrees is 2.5881904510252074e-01 // 76-74 = 2 away
sin() of -330.0 degrees is 5.0000000000000044e-01 // 44 away
// 0.5 5.0000000000000000e-01
sind() of -330.0 degrees is 4.9999999999999994e-01 // 6 away
sin() of -315.0 degrees is 7.0710678118654768e-01 // 68-52 = 16 away
// square root 0.5 --> 7.0710678118654752e-01
sind() of -315.0 degrees is 7.0710678118654746e-01 // 52-46 = 6 away
sin() of -300.0 degrees is 8.6602540378443860e-01
sind() of -300.0 degrees is 8.6602540378443871e-01
sin() of -285.0 degrees is 9.6592582628906842e-01
sind() of -285.0 degrees is 9.6592582628906831e-01
sin() of -270.0 degrees is 1.0000000000000000e+00 // Exact
sind() of -270.0 degrees is 1.0000000000000000e+00 // Exact
...
相关文章