Changeset 1004


Ignore:
Timestamp:
Oct 3, 2011, 1:36:34 AM (10 years ago)
Author:
sam
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/real.cpp

    r1003 r1004  
    708708real sin(real const &x)
    709709{
    710     real ret = 0.0, fact = 1.0, xn = x, x2 = x * x;
    711 
     710    bool switch_sign = x.m_signexp & 0x80000000u;
     711
     712    real absx = fmod(fabs(x), real::R_PI << 1);
     713    if (absx > real::R_PI)
     714    {
     715        absx -= real::R_PI;
     716        switch_sign = !switch_sign;
     717    }
     718
     719    if (absx > real::R_PI_2)
     720        absx = real::R_PI - absx;
     721
     722    real ret = 0.0, fact = 1.0, xn = absx, x2 = absx * absx;
    712723    for (int i = 1; ; i += 2)
    713724    {
     
    720731    }
    721732
     733    /* Propagate sign */
     734    if (switch_sign)
     735        ret.m_signexp ^= 0x80000000u;
    722736    return ret;
    723737}
     
    725739real cos(real const &x)
    726740{
    727     real ret = 0.0, fact = 1.0, xn = 1.0, x2 = x * x;
    728 
     741    bool switch_sign = false;
     742    real absx = fmod(fabs(x), real::R_PI << 1);
     743
     744    if (absx > real::R_PI)
     745        absx = (real::R_PI << 1) - absx;
     746
     747    if (absx > real::R_PI_2)
     748    {
     749        absx = real::R_PI - absx;
     750        switch_sign = true;
     751    }
     752
     753    real ret = 0.0, fact = 1.0, xn = 1.0, x2 = absx * absx;
    729754    for (int i = 1; ; i += 2)
    730755    {
     
    737762    }
    738763
     764    /* Propagate sign */
     765    if (switch_sign)
     766        ret.m_signexp ^= 0x80000000u;
    739767    return ret;
    740768}
Note: See TracChangeset for help on using the changeset viewer.