소스 검색

real: constrain sin() and cos() on real numbers so that they work properly

with large values. Until now they were evaluating the Taylor series even
for huge values.
legacy
Sam Hocevar sam 13 년 전
부모
커밋
b7fa88e210
1개의 변경된 파일30개의 추가작업 그리고 2개의 파일을 삭제
  1. +30
    -2
      src/real.cpp

+ 30
- 2
src/real.cpp 파일 보기

@@ -707,8 +707,19 @@ real fmod(real const &x, real const &y)

real sin(real const &x)
{
real ret = 0.0, fact = 1.0, xn = x, x2 = x * x;
bool switch_sign = x.m_signexp & 0x80000000u;

real absx = fmod(fabs(x), real::R_PI << 1);
if (absx > real::R_PI)
{
absx -= real::R_PI;
switch_sign = !switch_sign;
}

if (absx > real::R_PI_2)
absx = real::R_PI - absx;

real ret = 0.0, fact = 1.0, xn = absx, x2 = absx * absx;
for (int i = 1; ; i += 2)
{
real newret = ret + xn / fact;
@@ -719,13 +730,27 @@ real sin(real const &x)
fact *= (real)(-(i + 1) * (i + 2));
}

/* Propagate sign */
if (switch_sign)
ret.m_signexp ^= 0x80000000u;
return ret;
}

real cos(real const &x)
{
real ret = 0.0, fact = 1.0, xn = 1.0, x2 = x * x;
bool switch_sign = false;
real absx = fmod(fabs(x), real::R_PI << 1);

if (absx > real::R_PI)
absx = (real::R_PI << 1) - absx;

if (absx > real::R_PI_2)
{
absx = real::R_PI - absx;
switch_sign = true;
}

real ret = 0.0, fact = 1.0, xn = 1.0, x2 = absx * absx;
for (int i = 1; ; i += 2)
{
real newret = ret + xn / fact;
@@ -736,6 +761,9 @@ real cos(real const &x)
fact *= (real)(-i * (i + 1));
}

/* Propagate sign */
if (switch_sign)
ret.m_signexp ^= 0x80000000u;
return ret;
}



불러오는 중...
취소
저장