我是c ++的新手,并编写了一个小程序来查找角度的正弦和余弦值。我的示例代码如下:
#include <math.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define PI 3.14159265
int main ()
{
double rate, result;
rate = 90.0;
result = cos (rate*PI/180);
cout<<"The cosine of " << rate << " degrees is " << result <<endl;
return 0;
}
我得到1.7949e-009作为cos(90)的结果。有没有办法得到0作为结果(在结果变量中)而不是这种格式?同样的问题是180度的罪恶。我想要一个结果值为0的情况的一般解决方案。
答案 0 :(得分:3)
由于你标记了后期C ++而不是C,让我给你一些C ++提示:
<cmath>
而不是<math.h>
#define
更为惯用的方法来得出结果:
#include <cmath>
#include <iostream>
#include <iomanip>
int main ()
{
const auto PI = std::acos(-1); //let the computer to find out what PI is
double rate{}, result{}; //don't let uninitialized values
rate = 90.0;
result = std::cos (rate*PI/180);
std::cout<<"The cosine of " << // set outoput precison for floating point
std::setprecision(4) << rate << " degrees is " <<
std::setprecision(4) << result <<endl;
return 0;
}
注意我如何让std::
显式:C ++ <cmath>
对数学函数的重载比C更多。
请参阅:
另请注意,虽然更准确的PI使result
更准确,但总有可能结果不完美,因此 - 当显示浮点值时 - 将精度设置为足以在对您的问题有意义的水平上补偿换向误差。
实数的表示精度可以从std::numeric_limits<double>::digits10
(来自<limits>
标题)获得:切出2-3位数总是好的。
此外,在进行减法或比较时,请考虑舍入错误:请参阅std::numeric_limits::epsilon参考文档中的示例:
#include <cmath>
#include <limits>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <algorithm>
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
almost_equal(T x, T y, int ulp)
{
// the machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
// unless the result is subnormal
|| std::abs(x-y) < std::numeric_limits<T>::min();
}
int main()
{
double d1 = 0.2;
double d2 = 1 / std::sqrt(5) / std::sqrt(5);
if(d1 == d2)
std::cout << "d1 == d2\n";
else
std::cout << "d1 != d2\n";
if(almost_equal(d1, d2, 2))
std::cout << "d1 almost equals d2\n";
else
std::cout << "d1 does not almost equal d2\n";
}
显示sqrt(5)的平方不是...... 5,即使你设法看起来如此:
(剧透:outpu是
d1 != d2
d1 almost equals d2
); - )
答案 1 :(得分:0)
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
int main (){
double param, result;
param = 30.0;
result = sin (param*PI/180);
printf ("The sine of %f degrees is %f.\n", param, result );
return 0;
}
答案 2 :(得分:0)
结果是1.7949e-009,这是科学的方法,你可以使用固定的方式,甚至指定点的精度。
实际上1.7949e-009约为0.0000000017949。
用户krzaq指定输出格式为固定方式并设置精度2,它将打印:
the cosine of 90.0 degree is 0.00
除了你的PI还不够准确。
要获得高精度,您需要做的唯一额外事情是下载glm。 glm是一个优秀的数学派对,它在OpenGL数学函数中表现出色。 这是使用glm的代码:
#include <iostream>
#include <glm.hpp>
int main()
{
double Angle, Result;
Angle = 90.0;
Result = glm::cos(glm::radians(Angle));
std::cout << "The cosine of " << Angle << " degrees is " << std::fixed << Result << std::endl;
return 0;
}
答案 3 :(得分:0)
我试过M_PI,3.141592653589793238L或acos(-1l)。所有这些PI的近似值都不会在您的程序中完全生成0。 但是,至少你可以使用std :: setprecision和std :: fixed(在iomanip中)来显示0。 或者也许您可以使用自定义epsilon来舍入结果。
答案 4 :(得分:0)
有没有办法得到0作为结果[对于余弦(90°)]?
第1步,使用更准确的机器PI
第2步:不是转换为弧度然后调用cos()
,而是缩小范围,然后然后转换为弧度,然后调用cos()
。
范围减少可以使用fmod(x,360.0)
进行exactly,也可以使用trigonometric identifies进行进一步缩放。
This answer提供有关常规方法和详细sind(double degrees)
的信息。以下是结果值为0的情况的一般解决方案。This post讨论-0.0
问题。
// cos() of 90.0 degrees is 6.1232339957367660e-17
// cosd() of 90.0 degrees is 0.0000000000000000e+00
#include <cmath>
static double d2r(double d) {
static const auto PI = std::acos(-1);
return (d / 180.0) * PI;
}
double cosd(double x /* degrees */) {
if (!isfinite(x)) {
return std::cos(x);
}
int quo;
double x90 = std::remquo(std::fabs(x), 90.0, &quo);
double xr = d2r(x90);
switch (quo % 4) {
case 0:
return std::cos(xr);
case 1:
// Use + 0.0 to avoid -0.0
return std::sin(-xr + 0.0);
case 2:
return -std::cos(xr);
case 3:
return std::sin(xr + 0.0);
}
return 0.0;
}