Mercurial > hg > octave-avbm
changeset 11211:2554b4a0806e
use templates for some lo-mappers functions
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 09 Nov 2010 03:24:18 -0500 |
parents | b79924abf776 |
children | ce27d6f4e134 |
files | liboctave/ChangeLog liboctave/lo-mappers.cc liboctave/lo-mappers.h liboctave/lo-utils.cc liboctave/lo-utils.h |
diffstat | 5 files changed, 182 insertions(+), 258 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,16 @@ +2010-11-09 John W. Eaton <jwe@octave.org> + + * lo-mappers.cc, lo-mappers.h (xmod, xrem): Move definitions + from lo-mappers.cc to lo-mappers.h and convert to templates. + (xtrunc): Move definitions from lo-mappers.cc to lo-mappers.h. + * lo-mappers.cc (fix): Use xtrunc. + * lo-mappers.h (xfloor): New functions. + (X_NINT): New template function. + (D_NINT, F_NINT): Define in terms of X_NINT. + * lo-utils.h, lo-utils.cc (D_NINT, F_NINT): Delete. + * lo-mappers.h, lo-mappers.cc (NINTbig, NINT): Move from + lo-utils.cc and lo-utils.h. + 2010-11-09 John W. Eaton <jwe@octave.org> * Array.cc (Array<T>::sort, Array<T>::is_sorted,
--- a/liboctave/lo-mappers.cc +++ b/liboctave/lo-mappers.cc @@ -55,7 +55,7 @@ double fix (double x) { - return gnulib::trunc (x); + return xtrunc (x); } double @@ -76,12 +76,6 @@ return gnulib::round (x); } -double -xtrunc (double x) -{ - return gnulib::trunc (x); -} - double xroundb (double x) { @@ -107,88 +101,6 @@ } double -xmod (double x, double y) -{ - double retval; - - if (y == 0) - retval = x; - else - { - double q = x / y; - - double n = floor (q); - - if (D_NINT (y) != y) - { - if (D_NINT (q) == q) - n = q; - else - { - if (x >= -1 && x <= 1) - { - if (std::abs (q - D_NINT (q)) < DBL_EPSILON) - n = D_NINT (q); - } - else - { - if (std::abs ((q - D_NINT (q))/ D_NINT (q)) < DBL_EPSILON) - n = D_NINT (q); - } - } - } - - retval = x - y * n; - } - - if (x != y && y != 0) - retval = copysignf (retval, y); - - return retval; -} - -double -xrem (double x, double y) -{ - double retval; - - if (y == 0) - retval = x; - else - { - double q = x / y; - - double n = trunc (q); - - if (D_NINT (y) != y) - { - if (D_NINT (q) == q) - n = q; - else - { - if (x >= -1 && x <= 1) - { - if (std::abs (q - D_NINT (q)) < DBL_EPSILON) - n = D_NINT (q); - } - else - { - if (std::abs ((q - D_NINT (q))/ D_NINT (q)) < DBL_EPSILON) - n = D_NINT (q); - } - } - } - - retval = x - y * n; - } - - if (x != y && y != 0) - retval = copysignf (retval, x); - - return retval; -} - -double xlog2 (double x) { #if defined (HAVE_LOG2) @@ -416,7 +328,7 @@ float fix (float x) { - return gnulib::truncf (x); + return xtrunc (x); } float @@ -437,12 +349,6 @@ return gnulib::round (x); } -float -xtrunc (float x) -{ - return gnulib::truncf (x); -} - float xroundb (float x) { @@ -468,88 +374,6 @@ } float -xmod (float x, float y) -{ - float retval; - - if (y == 0) - retval = x; - else - { - float q = x / y; - - float n = floor (q); - - if (F_NINT (y) != y) - { - if (F_NINT (q) == q) - n = q; - else - { - if (x >= -1 && x <= 1) - { - if (std::abs (q - F_NINT (q)) < FLT_EPSILON) - n = F_NINT (q); - } - else - { - if (std::abs ((q - F_NINT (q))/ F_NINT (q)) < FLT_EPSILON) - n = F_NINT (q); - } - } - } - - retval = x - y * n; - } - - if (x != y && y != 0) - retval = copysignf (retval, y); - - return retval; -} - -float -xrem (float x, float y) -{ - float retval; - - if (y == 0) - retval = x; - else - { - float q = x / y; - - float n = truncf (q); - - if (F_NINT (y) != y) - { - if (F_NINT (q) == q) - n = q; - else - { - if (x >= -1 && x <= 1) - { - if (std::abs (q - F_NINT (q)) < FLT_EPSILON) - n = F_NINT (q); - } - else - { - if (std::abs ((q - F_NINT (q))/ F_NINT (q)) < FLT_EPSILON) - n = F_NINT (q); - } - } - } - - retval = x - y * n; - } - - if (x != y && y != 0) - retval = copysignf (retval, x); - - return retval; -} - -float xlog2 (float x) { #if defined (HAVE_LOG2) @@ -852,3 +676,52 @@ bool xnegative_sign (float x) { return __lo_ieee_float_signbit (x); } + +// Convert X to the nearest integer value. Should not pass NaN to +// this function. + +// Sometimes you need a large integer, but not always. + +octave_idx_type +NINTbig (double x) +{ + if (x > std::numeric_limits<octave_idx_type>::max ()) + return std::numeric_limits<octave_idx_type>::max (); + else if (x < std::numeric_limits<octave_idx_type>::min ()) + return std::numeric_limits<octave_idx_type>::min (); + else + return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +octave_idx_type +NINTbig (float x) +{ + if (x > std::numeric_limits<octave_idx_type>::max ()) + return std::numeric_limits<octave_idx_type>::max (); + else if (x < std::numeric_limits<octave_idx_type>::min ()) + return std::numeric_limits<octave_idx_type>::min (); + else + return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +int +NINT (double x) +{ + if (x > std::numeric_limits<int>::max ()) + return std::numeric_limits<int>::max (); + else if (x < std::numeric_limits<int>::min ()) + return std::numeric_limits<int>::min (); + else + return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +int +NINT (float x) +{ + if (x > std::numeric_limits<int>::max ()) + return std::numeric_limits<int>::max (); + else if (x < std::numeric_limits<int>::min ()) + return std::numeric_limits<int>::min (); + else + return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); +}
--- a/liboctave/lo-mappers.h +++ b/liboctave/lo-mappers.h @@ -25,10 +25,16 @@ #if !defined (octave_liboctave_mappers_h) #define octave_liboctave_mappers_h 1 +#include <limits> + #include "oct-cmplx.h" #include "lo-math.h" // Double Precision +inline double xtrunc (double x) { return gnulib::trunc (x); } +inline double xcopysign (double x, double y) { return copysignf (x, y); } +inline double xfloor (double x) { return floor (x); } + extern OCTAVE_API double arg (double x); extern OCTAVE_API double conj (double x); extern OCTAVE_API double fix (double x); @@ -37,9 +43,6 @@ extern OCTAVE_API double xround (double x); extern OCTAVE_API double xroundb (double x); extern OCTAVE_API double signum (double x); -extern OCTAVE_API double xtrunc (double x); -extern OCTAVE_API double xmod (double x, double y); -extern OCTAVE_API double xrem (double x, double y); extern OCTAVE_API double xlog2 (double x); extern OCTAVE_API Complex xlog2 (const Complex& x); extern OCTAVE_API double xlog2 (double x, int& exp); @@ -119,6 +122,10 @@ extern OCTAVE_API Complex xmax (const Complex& x, const Complex& y); // Single Precision +inline float xtrunc (float x) { return gnulib::truncf (x); } +inline float xcopysign (float x, float y) { return copysignf (x, y); } +inline float xfloor (float x) { return floorf (x); } + extern OCTAVE_API float arg (float x); extern OCTAVE_API float conj (float x); extern OCTAVE_API float fix (float x); @@ -127,9 +134,6 @@ extern OCTAVE_API float xround (float x); extern OCTAVE_API float xroundb (float x); extern OCTAVE_API float signum (float x); -extern OCTAVE_API float xtrunc (float x); -extern OCTAVE_API float xmod (float x, float y); -extern OCTAVE_API float xrem (float x, float y); extern OCTAVE_API float xlog2 (float x); extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x); extern OCTAVE_API float xlog2 (float x, int& exp); @@ -224,5 +228,113 @@ extern OCTAVE_API bool xnegative_sign (double x); extern OCTAVE_API bool xnegative_sign (float x); +extern OCTAVE_API octave_idx_type NINTbig (double x); +extern OCTAVE_API octave_idx_type NINTbig (float x); + +extern OCTAVE_API int NINT (double x); +extern OCTAVE_API int NINT (float x); + +template <typename T> +OCTAVE_API +T +X_NINT (T x) +{ + return (xisinf (x) || xisnan (x)) ? x : xfloor (x + 0.5); +} + +inline OCTAVE_API double D_NINT (double x) { return X_NINT (x); } +inline OCTAVE_API float F_NINT (float x) { return X_NINT (x); } + +// Template functions can have either float or double arguments. + +template <typename T> +OCTAVE_API +T +xmod (T x, T y) +{ + T retval; + + if (y == 0) + retval = x; + else + { + T q = x / y; + + T n = floor (q); + + if (X_NINT (y) != y) + { + if (X_NINT (q) == q) + n = q; + else + { + if (x >= -1 && x <= 1) + { + if (std::abs (q - X_NINT (q)) + < std::numeric_limits<T>::epsilon ()) + n = X_NINT (q); + } + else + { + if (std::abs ((q - X_NINT (q))/ X_NINT (q)) + < std::numeric_limits<T>::epsilon ()) + n = D_NINT (q); + } + } + } + + retval = x - y * n; + } + + if (x != y && y != 0) + retval = xcopysign (retval, y); + + return retval; +} + +template <typename T> +OCTAVE_API +T +xrem (T x, T y) +{ + T retval; + + if (y == 0) + retval = x; + else + { + T q = x / y; + + T n = xtrunc (q); + + if (X_NINT (y) != y) + { + if (X_NINT (q) == q) + n = q; + else + { + if (x >= -1 && x <= 1) + { + if (std::abs (q - X_NINT (q)) + < std::numeric_limits<T>::epsilon ()) + n = X_NINT (q); + } + else + { + if (std::abs ((q - X_NINT (q))/ X_NINT (q)) + < std::numeric_limits<T>::epsilon ()) + n = X_NINT (q); + } + } + } + + retval = x - y * n; + } + + if (x != y && y != 0) + retval = xcopysign (retval, x); + + return retval; +} #endif
--- a/liboctave/lo-utils.cc +++ b/liboctave/lo-utils.cc @@ -45,73 +45,6 @@ #include "lo-mappers.h" #include "lo-utils.h" -// Convert X to the nearest integer value. Should not pass NaN to -// this function. - -// Sometimes you need a large integer, but not always. - -octave_idx_type -NINTbig (double x) -{ - if (x > std::numeric_limits<octave_idx_type>::max ()) - return std::numeric_limits<octave_idx_type>::max (); - else if (x < std::numeric_limits<octave_idx_type>::min ()) - return std::numeric_limits<octave_idx_type>::min (); - else - return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -octave_idx_type -NINTbig (float x) -{ - if (x > std::numeric_limits<octave_idx_type>::max ()) - return std::numeric_limits<octave_idx_type>::max (); - else if (x < std::numeric_limits<octave_idx_type>::min ()) - return std::numeric_limits<octave_idx_type>::min (); - else - return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -int -NINT (double x) -{ - if (x > std::numeric_limits<int>::max ()) - return std::numeric_limits<int>::max (); - else if (x < std::numeric_limits<int>::min ()) - return std::numeric_limits<int>::min (); - else - return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -int -NINT (float x) -{ - if (x > std::numeric_limits<int>::max ()) - return std::numeric_limits<int>::max (); - else if (x < std::numeric_limits<int>::min ()) - return std::numeric_limits<int>::min (); - else - return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -double -D_NINT (double x) -{ - if (xisinf (x) || xisnan (x)) - return x; - else - return floor (x + 0.5); -} - -float -F_NINT (float x) -{ - if (xisinf (x) || xisnan (x)) - return x; - else - return floor (x + 0.5); -} - bool xis_int_or_inf_or_nan (double x) { return xisnan (x) || D_NINT (x) == x; }
--- a/liboctave/lo-utils.h +++ b/liboctave/lo-utils.h @@ -32,13 +32,6 @@ #include "oct-cmplx.h" #include "syswait.h" -extern OCTAVE_API octave_idx_type NINTbig (double x); -extern OCTAVE_API octave_idx_type NINTbig (float x); -extern OCTAVE_API int NINT (double x); -extern OCTAVE_API int NINT (float x); -extern OCTAVE_API double D_NINT (double x); -extern OCTAVE_API float F_NINT (float x); - extern OCTAVE_API bool xis_int_or_inf_or_nan (double x); extern OCTAVE_API bool xis_one_or_zero (double x); extern OCTAVE_API bool xis_zero (double x);