我尝试使用sine
和Taylor Series创建一个自定义c
函数,用于计算系列中包含10个术语的sin
,但我得到了当我尝试找到sine(x)
x > 6
时的错误结果。
适用于-5 < x < 5
,但超出该范围的任何内容都无法产生正确的结果。
我希望sin(10)
返回接近-0.5440
的内容,但获取1418.0269775391
我已将所有内容放在一个文件中,因此更容易。
#include <stdio.h>
#include <stdlib.h>
double factorial(double n);
double power(double n, double pow);
double sine(double n);
// This is supposed to all go in a .c file and reference the .h stuff above
// This is the actual implementation of the functions declared above
double factorial(double n) {
// 0! = 1 so just return it
if(n == 0) {
return 1;
}
// Recursively call factorial with n-1 until n == 0
return n * (factorial(n - 1));
}
double power(double n, double power) {
double result = n;
// Loop as many times as the power and just multiply itself power amount of times
for(int i = 1; i < power; i++) {
result = n * result;
}
return result;
}
double sine(double n) {
double result = n;
double coefficent = 3; // Increment this by 2 each loop
for(int i = 0; i < 10; i++) { // Change 10 to go out to more/less terms
double pow = power(n, coefficent);
double frac = factorial(coefficent);
printf("Loop %d:\n%2.3f ^ %2.3f = %2.3f\n", i, n, coefficent, pow);
printf("%2.3f! = %2.3f\n", coefficent, frac);
// Switch between adding/subtracting
if(i % 2 == 0) { // If the index of the loop is divided by 2, the index is even, so subtract
result = result - (pow/frac); // x - ((x^3)/(3!)) - ((x^5)/(5!))...
} else {
result = result + (pow/frac); // x - ((x^3)/(3!)) + ((x^5)/(5!))...
}
coefficent = coefficent + 2;
printf("Result = %2.3f\n\n", result);
}
return result;
}
// main starting point. This is suppossed to #include "functions.c" which contain the above functions in it
int main(int argc, char** argv) {
double number = atof(argv[1]); // argv[1] = "6"
double sineResult = sine(number);
printf("%1.10f", sineResult);
return (0);
}
答案 0 :(得分:2)
正如我在Python: Calculate sine/cosine with a precision of up to 1 million digits
中所说的那样以 x 0 为中心的真实泰勒展开是:
其中 R n 是拉格朗日剩余
请注意,只要 x 离开中心, R n 就会快速增长 X <子> 0 子>
由于您正在实施 Maclaurin系列(泰勒系列 以0)为中心而不是一般的泰勒系列,你的功能 在尝试计算 sin(x)时会给出非常错误的结果 x 的重要值。
因此,在您for
函数的sine()
循环之前,您必须将域名减少到至少 [ - pi,pi] ...如果将其减少到 [0,pi] 并利用正弦的奇偶校验。
要修复您的代码,您需要math.h
fmod()
,所以您可以这样做:
#include <math.h>
// Your code
double sine (double n) {
// Define PI
const double my_pi = 3.14159265358979323846;
// Sine's period is 2*PI
n = fmod(n, 2 * my_pi);
// Any negative angle can be brought back
// to it's equivalent positive angle
if (n < 0) {
n = 2 * my_pi - n;
}
// Sine is an odd function...
// let's take advantage of it.
char sign = 1;
if (n > my_pi) {
n -= my_pi;
sign = -1;
}
// Now n is in range [0, PI].
// The rest of your function is fine
return sign * result;
}
现在如果你真的讨厌math.h
模块,你可以像这样实现自己的fmod()
,
double fmod(double a, double b)
{
double frac = a / b;
int floor = frac > 0 ? (int)frac : (int)(frac - 0.9999999999999999);
return (a - b * floor);
}
答案 1 :(得分:0)
在我对问题的评论中列出的更正后,建议的代码如下:
dataFrame.write.parquet(s3Path)
,结果输出如下:
#include <stdio.h>
#include <stdlib.h>
double factorial(double n);
double power(double n, double pow);
double sine(double n);
// This is supposed to all go in a .c file and reference the .h stuff above
// This is the actual implementation of the functions declared above
double factorial(double n) {
// 0! = 1 so just return it
if(n == 0) {
return 1;
}
// Recursively call factorial with n-1 until n == 0
return n * (factorial(n - 1));
}
double power(double n, double power) {
double result = n;
// Loop as many times as the power and just multiply itself power amount of times
for(int i = 1; i < power; i++) {
result = n * result;
}
return result;
}
double sine(double n) {
double result = n;
double coefficent = 3.0; // Increment this by 2 each loop
for(int i = 0; i < 10; i++) { // Change 10 to go out to more/less terms
double pow = power(n, coefficent);
double frac = factorial(coefficent);
printf("Loop %d:\n%2.3f ^ %2.3f = %2.3f\n", i, n, coefficent, pow);
printf("%2.3f! = %2.3f\n", coefficent, frac);
// Switch between adding/subtracting
if(i % 2 == 0) { // If the index of the loop is divided by 2, the index is even, so subtract
result = result - (pow/frac); // x - ((x^3)/(3!)) - ((x^5)/(5!))...
} else {
result = result + (pow/frac); // x - ((x^3)/(3!)) + ((x^5)/(5!))...
}
coefficent = coefficent + 2;
printf("Result = %2.3f\n\n", result);
}
return result;
}
// main starting point. This is suppossed to #include "functions.c" which contain the above functions in it
int main( void )
{
double number = atof("6");
double sineResult = sine(number);
printf("%1.10f", sineResult);
return (0);
}
答案 2 :(得分:0)
泰勒展开的误差取决于参数范围以及泰勒展开的顺序。我相信你已经超越了论证的界限。有关更多示例,请参见此处:www.dotancohen.com/eng/taylor-sine.php