# HG changeset patch # User John W. Eaton # Date 1289291058 18000 # Node ID 2554b4a0806e7faac456e20f712aedf1c6b02fcc # Parent b79924abf776260b095d7941c7fee689f9f077d7 use templates for some lo-mappers functions diff -r b79924abf776 -r 2554b4a0806e liboctave/ChangeLog --- a/liboctave/ChangeLog Tue Nov 09 01:28:45 2010 -0500 +++ b/liboctave/ChangeLog Tue Nov 09 03:24:18 2010 -0500 @@ -1,3 +1,16 @@ +2010-11-09 John W. Eaton + + * 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 * Array.cc (Array::sort, Array::is_sorted, diff -r b79924abf776 -r 2554b4a0806e liboctave/lo-mappers.cc --- a/liboctave/lo-mappers.cc Tue Nov 09 01:28:45 2010 -0500 +++ b/liboctave/lo-mappers.cc Tue Nov 09 03:24:18 2010 -0500 @@ -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::max ()) + return std::numeric_limits::max (); + else if (x < std::numeric_limits::min ()) + return std::numeric_limits::min (); + else + return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +octave_idx_type +NINTbig (float x) +{ + if (x > std::numeric_limits::max ()) + return std::numeric_limits::max (); + else if (x < std::numeric_limits::min ()) + return std::numeric_limits::min (); + else + return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +int +NINT (double x) +{ + if (x > std::numeric_limits::max ()) + return std::numeric_limits::max (); + else if (x < std::numeric_limits::min ()) + return std::numeric_limits::min (); + else + return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + +int +NINT (float x) +{ + if (x > std::numeric_limits::max ()) + return std::numeric_limits::max (); + else if (x < std::numeric_limits::min ()) + return std::numeric_limits::min (); + else + return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); +} diff -r b79924abf776 -r 2554b4a0806e liboctave/lo-mappers.h --- a/liboctave/lo-mappers.h Tue Nov 09 01:28:45 2010 -0500 +++ b/liboctave/lo-mappers.h Tue Nov 09 03:24:18 2010 -0500 @@ -25,10 +25,16 @@ #if !defined (octave_liboctave_mappers_h) #define octave_liboctave_mappers_h 1 +#include + #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 +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 +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::epsilon ()) + n = X_NINT (q); + } + else + { + if (std::abs ((q - X_NINT (q))/ X_NINT (q)) + < std::numeric_limits::epsilon ()) + n = D_NINT (q); + } + } + } + + retval = x - y * n; + } + + if (x != y && y != 0) + retval = xcopysign (retval, y); + + return retval; +} + +template +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::epsilon ()) + n = X_NINT (q); + } + else + { + if (std::abs ((q - X_NINT (q))/ X_NINT (q)) + < std::numeric_limits::epsilon ()) + n = X_NINT (q); + } + } + } + + retval = x - y * n; + } + + if (x != y && y != 0) + retval = xcopysign (retval, x); + + return retval; +} #endif diff -r b79924abf776 -r 2554b4a0806e liboctave/lo-utils.cc --- a/liboctave/lo-utils.cc Tue Nov 09 01:28:45 2010 -0500 +++ b/liboctave/lo-utils.cc Tue Nov 09 03:24:18 2010 -0500 @@ -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::max ()) - return std::numeric_limits::max (); - else if (x < std::numeric_limits::min ()) - return std::numeric_limits::min (); - else - return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -octave_idx_type -NINTbig (float x) -{ - if (x > std::numeric_limits::max ()) - return std::numeric_limits::max (); - else if (x < std::numeric_limits::min ()) - return std::numeric_limits::min (); - else - return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -int -NINT (double x) -{ - if (x > std::numeric_limits::max ()) - return std::numeric_limits::max (); - else if (x < std::numeric_limits::min ()) - return std::numeric_limits::min (); - else - return static_cast ((x > 0) ? (x + 0.5) : (x - 0.5)); -} - -int -NINT (float x) -{ - if (x > std::numeric_limits::max ()) - return std::numeric_limits::max (); - else if (x < std::numeric_limits::min ()) - return std::numeric_limits::min (); - else - return static_cast ((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; } diff -r b79924abf776 -r 2554b4a0806e liboctave/lo-utils.h --- a/liboctave/lo-utils.h Tue Nov 09 01:28:45 2010 -0500 +++ b/liboctave/lo-utils.h Tue Nov 09 03:24:18 2010 -0500 @@ -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);