三角自变量约简(模2π的约简) [英] Trigonometric argument reduction (reduction modulo 2π)

查看:58
本文介绍了三角自变量约简(模2π的约简)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为正弦和余弦创建一个计算器,该计算器在技术上仅在0-pi/2的范围内运行.现在看来这很愚蠢,但以后会用到,所以我可以采用泰勒级数.

I am trying to create a calculator for sin and cosine that technically only operates on the range of 0-pi/2. Right now this might seem silly but later on it will be used so I can employ Taylor series.

我有一个最有效的实现,但是当theta的形式为x *(pi/2)时,我遇到了一个严重的问题,其中x是任意整数.似乎在这些值上有时会将它们推入它们不属于的附近象限.还有一些偶然的完全错误,我无法解释.

I have a mostly working implementation however I have a serious issue when theta is in the form of x * (pi/2) where x is an arbitrary integer. It would appear that on these values that sometimes they are pushed into a nearby quadrants they dont belong to. There are also some occasional outright errors that I cannot explain.

我该如何提高效率和正确性?

How can I shore this up making it more efficient and correct?

这是执行此操作的代码.

Here is the code for doing this.

#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;
    }
}

推荐答案

您遇到了一个长期存在且经常无法识别的问题区域,称为数字库中真正解决此问题,我必须有效地实现任意精度浮点算法,并存储一个320位(1078位)的PI常数.libc的某些实现为您有效地做到了这一点,但并非全部实现,因此您不能放心地假设它.

You are running into a long-standing and often-unrecognized problem area called range reduction. The basic problem is that a float PI constant is only defined 8 digit accuracy, so by the time you are trying to compute (x - n * PI) for n ~ 10^4, you have lost half the digits of accuracy in your results, and worse as n gets larger. There is no simple software solution to this problem. To really solve it in my own numerical library, I had to effectively implement arbitrary-precision floating point arithmetic and store a 320-digit (1078-bit) PI constant. Some implementations of libc effectively do this for you, but not all, so you can't safely assume it.

这篇关于三角自变量约简(模2π的约简)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆