Browse Source

core: implement frexp(), ldexp() and modf() for reals.

legacy
Sam Hocevar sam 13 years ago
parent
commit
b6b8044442
2 changed files with 62 additions and 2 deletions
  1. +58
    -0
      src/real.cpp
  2. +4
    -2
      src/real.h

+ 58
- 0
src/real.cpp View File

@@ -770,6 +770,38 @@ real cosh(real const &x)
return (exp(x) + exp(-x)) >> 1;
}

real frexp(real const &x, int *exp)
{
if (!x)
{
*exp = 0;
return x;
}

real ret = x;
int exponent = (ret.m_signexp & 0x7fffffffu) - (1 << 30) + 1;
*exp = exponent + 1;
ret.m_signexp -= exponent + 1;
return ret;
}

real ldexp(real const &x, int exp)
{
real ret = x;
if (ret)
ret.m_signexp += exp;
return ret;
}

real modf(real const &x, real *iptr)
{
real absx = fabs(x);
real tmp = floor(absx);

*iptr = copysign(tmp, x);
return copysign(absx - tmp, x);
}

real copysign(real const &x, real const &y)
{
real ret = x;
@@ -1063,6 +1095,32 @@ real atan(real const &x)
return ret;
}

real atan2(real const &y, real const &x)
{
if (!y)
{
if ((x.m_signexp >> 31) == 0)
return y;
if (y.m_signexp >> 31)
return -real::R_PI;
return real::R_PI;
}

if (!x)
{
if (y.m_signexp >> 31)
return -real::R_PI;
return real::R_PI;
}

/* FIXME: handle the Inf and NaN cases */
real z = y / x;
real ret = atan(z);
if (x < real::R_0)
ret += (y > real::R_0) ? real::R_PI : -real::R_PI;
return ret;
}

void real::hexprint() const
{
printf("%08x", m_signexp);


+ 4
- 2
src/real.h View File

@@ -69,7 +69,7 @@ public:
friend real asin(real const &x);
friend real acos(real const &x);
friend real atan(real const &x);
/* FIXME: atan2 */
friend real atan2(real const &y, real const &x);

/* Hyperbolic functions */
friend real sinh(real const &x);
@@ -82,7 +82,9 @@ public:
friend real log(real const &x);
friend real log2(real const &x);
friend real log10(real const &x);
/* FIXME: frexp ldexp modf */
friend real frexp(real const &x, int *exp);
friend real ldexp(real const &x, int exp);
friend real modf(real const &x, real *iptr);

/* Power functions */
friend real re(real const &x);


Loading…
Cancel
Save