首先让我说这是我学习 C 的第四天,如果我的代码不够简洁,请原谅我,但我相信它可以完成工作。此外,我想练习编写所有数学函数,因为我觉得如果我自己编写它们会受益更多。我的编译器是 GNU gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
当我编写一个将度数转换为弧度的函数时,我遇到了这个错误。当我将 15 度的弧度值处理到我的源代码中时,我得到了正确的答案。然后我编写了从弧度转换角度的函数,用它来获取 15 度的弧度值,并将其插入到我的 sin(x) 函数中,它返回了一个不正确的值。
然后我测试了很多不同的场景来尝试调试我的代码(正如你在所有 *printf*s 中看到的那样)。然后我打印了我计算的弧度值的值(到 54 位十进制数字)并将该数字复制到我的源代码中......答案是正确的。
所以我的问题是:在什么情况下使用计算值与使用相同的计算值不同,但直接复制到源代码中?
我知道编译器会自动转换任何文字值,如果它们与函数采用的参数类型不同,但就我而言,我不明白它有何不同。
这是代码。再次,抱歉,如果它非常缓慢,但是,嘿,这仅用于学习目的:) 任何帮助将不胜感激,我只是无法理解可能导致这种情况的原因,而且我 4 小时的研究无济于事。
#include <stdio.h>
#define EPSILON 0.000001
#define PI 3.14159
double sin(double x);
int fact(int x);
double powr(double x, int power);
double deg_to_rad(double degrees);
int main(int argc, char *argv[]){
double radian = deg_to_rad((double)15);
printf("Correct answer = 0.25881883\n\n");
printf("Sin approximation using constant .26179917: %1.8f\n\n", sin(.26179917));
printf("Radian variable calculated by deg_to_rad(15): %1.54f\n", radian);
printf("Sin approximation using radian variable: %1.8f\n\n", sin(radian));
printf("Sin approximation using radian variable's value (0.261799166666666638381144593950011767446994781494140625) copied and pasted into source: %1.8f\n", sin(0.261799166666666638381144593950011767446994781494140625));
return 0;
}
double deg_to_rad(double degrees){
return ((degrees/180) * PI);
}
double abs_val(double x){
if (x < 0){
return (-x);
}
else{
return x;
}
}
int fact(int x){
if (x > 1){
return (x * fact(x - 1));
}
else return 1;
}
double powr(double x, int power){
if (power < 1){
if (power == 0){
return 1.0L;
}
else{
puts("This functionality is not yet built in to this function.");
return 0.0L;
}
}
else if (power > 1){
return (x * powr(x , power - 1));
}
//If power is 1.
else return x;
}
/*
* Based on the Taylor series: sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - ... + (-1)^(n-1)*x^(2n-1)/(2n-1)! + ....
*/
double sin(double x){
static int n = 0;
n++;
double result = (powr(-1.0L,n - 1) * (powr(x, (2*n - 1)) / fact(2*n - 1)));
//If the current n is odd.
if (n % 2){
if (abs_val(result) > EPSILON){
return (result + sin(x));
}
else {
//Reset n and now begin returning from recursions.
n = 0;
return result;
}
}
else {
if (abs_val(result) > EPSILON){
return (-result + sin(x));
}
else {
//reset n and now begin returning recurstion
n = 0;
return result;
}
}
}