Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
三角变元约化(约化模2π;)_C_Math_Trigonometry - Fatal编程技术网

三角变元约化(约化模2π;)

三角变元约化(约化模2π;),c,math,trigonometry,C,Math,Trigonometry,我正在尝试创建一个计算正弦和余弦的计算器,从技术上讲,它只能在0-pi/2的范围内运行。现在这可能看起来很愚蠢,但稍后将使用它,以便我可以使用泰勒级数 我有一个主要工作的实现,但是当θ是x*(pi/2)的形式时,我有一个严重的问题,其中x是一个任意整数。看起来,在这些值上,有时它们会被推到不属于它们的邻近象限中。还有一些我无法解释的偶然的直接错误 我怎样才能使它更加有效和正确 下面是执行此操作的代码 #define T_PI (2.0 * M_PI) #define H_PI (0.5 * M_

我正在尝试创建一个计算正弦和余弦的计算器,从技术上讲,它只能在0-pi/2的范围内运行。现在这可能看起来很愚蠢,但稍后将使用它,以便我可以使用泰勒级数

我有一个主要工作的实现,但是当θ是x*(pi/2)的形式时,我有一个严重的问题,其中x是一个任意整数。看起来,在这些值上,有时它们会被推到不属于它们的邻近象限中。还有一些我无法解释的偶然的直接错误

我怎样才能使它更加有效和正确

下面是执行此操作的代码

#define T_PI (2.0 * M_PI)
#define H_PI (0.5 * M_PI)
void sincos(float theta, float* cosine, float* cosine) {
  int mode;
  prepareForRange(&theta, cosine, sine);
  Assert(!(f < 0.0 || f > H_PI));
  *cosine = cos(theta);
  *sine = sin(theta);
  range_output(mode, cosine, sine);
}
void prepareForRange(float* theta, int* mode, float *cosine, float* sine) {
  if (*theta < 0.0) *theta += ceil(-*theta / T_PI) * T_PI;
  *mode = (int)floor(*theta / H_PI) % 4 + 1;
  *theta = fmodf(*theta, H_PI);
}
void range_output(int mode, float *cos, float *sin) {
  float temp;
  switch (mode) {
    case 1:
      break;
    case 2:
      temp = *cos;
      *cos = -*sin;
      *sin = temp;
      break;
    case 3:
      *cos = -*cos;
      *sin = -*sin;
      break;
    case 4:
      temp = *cos;
      *cos = *sin;
      *sin = -temp;
      break;
    default:
      break;
    }
}
#定义T#PI(2.0*M#PI)
#定义H_PI(0.5*M_PI)
空正弦(浮点θ、浮点*余弦、浮点*余弦){
int模式;
准备安排(&θ、余弦、正弦);
断言(!(f<0.0|f>H|PI));
*余弦=余弦(θ);
*正弦=正弦(θ);
量程输出(模式、余弦、正弦);
}
无效准备安排(浮点*θ、整数*模式、浮点*余弦、浮点*正弦){
如果(*θ<0.0)*θ+=ceil(-*θ/T_π)*T_π;
*模式=(内部)楼层(*θ/H_π)%4+1;
*θ=fmodf(*θ,H_-PI);
}
无效范围_输出(整数模式、浮点*cos、浮点*sin){
浮子温度;
开关(模式){
案例1:
打破
案例2:
温度=*cos;
*cos=-*sin;
*sin=温度;
打破
案例3:
*cos=-*cos;
*sin=-*sin;
打破
案例4:
温度=*cos;
*cos=*sin;
*sin=-temp;
打破
违约:
打破
}
}

您遇到了一个长期存在且经常无法识别的问题领域,名为。基本问题是,浮点PI常数的定义精度仅为8位,因此,当您试图计算n~10^4的(x-n*PI)时,结果中的精度已经降低了一半,并且随着n的增大,精度会变得更差。这个问题没有简单的软件解决方案。为了真正解决这个问题,我必须有效地实现任意精度浮点运算,并存储一个320位(1078位)的PI常量。libc的一些实现可以有效地为您做到这一点,但不是全部,因此您不能安全地假设它。

当您发布这样的问题时,您应该至少包括一个输入案例,它不能产生所需的结果,以及您从代码中获得的结果和预期的结果。代码可能存在浮点舍入问题。浮点数不能精确地表示实数。特别是,
M_PI
不能精确为π,使用
M_PI
的倍数将使偏差成倍增加。有关正确算法的详细信息,请参阅。我的方法是使用类似的约简,但涉及有理数:
k=prepareForRange(int x2)
。那么你的函数sincos(x)的形式是
sincos(k*pi)
其中
k
是三角约化分数。
浮点pi常数仅定义为8位精度
你从哪里得到的?OP声明了一个
double
M_-PI,精度约为15-17位,在变量和参数中只能转换为
float
。无论如何,如果精度为8,则单个精度
浮点
只有~7位数字。请注意@LưuVĩnhPhúc:我同意你所有的挑剔。当然,这些都不是问题的核心,这就是他的PI和使用它的算术运算远没有达到缩小范围所需的精度。