diff options
Diffstat (limited to 'src/jtutil/util++2.hh')
-rw-r--r-- | src/jtutil/util++2.hh | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/jtutil/util++2.hh b/src/jtutil/util++2.hh new file mode 100644 index 0000000..9c37159 --- /dev/null +++ b/src/jtutil/util++2.hh @@ -0,0 +1,119 @@ +// util++.hh -- stuff for my C++ utility library +// $Id$ +// +// jtutil::{min,max} - min/max templates +// jtutil::abs - absolute value template +// jtutil::pow* - raise floating point value to small-integer power +// fuzzy::<fpt> - fuzzy floating point comparisons and other operations +// round::<fpt> - floating point rounding +// + +//****************************************************************************** + +namespace jtutil + { + +// how many integers are in the closed interval [low,high] +inline int how_many_in_range(int low, int high) + { return high - low + 1; } + +// +// minimum/maximum templates (valid for both integer and floating-point types) +// FIXME: these are supposed to be in the STL, +// but in practice they often aren't (yet) :( +// eg the gcc 2.95.2 library doesn't have them :( +// +template <typename num> + inline num min(num x, num y) { return x < y ? x : y; }; +template <typename num> + inline num max(num x, num y) { return x > y ? x : y; }; + +// +// absolute value template +// FIXME: this ought to be somewhere in the STL? +// +template <typename fpt> + inline fpt abs(fpt x) { return (x > 0.0) ? x : -x; } + +// +// These functions raise their arguments (presumably floating-point) +// to various small-integer powers. +// FIXME: do we ever use these? +// +template <typename fpt> + inline fpt pow2(fpt x) { return x*x; } +template <typename fpt> + inline fpt pow3(fpt x) { return x*x*x; } +template <typename fpt> + inline fpt pow4(fpt x) { return pow2(pow2(x)); } +template <typename fpt> + inline fpt pow5(fpt x) { return x * pow4(x); } +template <typename fpt> + inline fpt pow6(fpt x) { return pow3(pow2(x)); } +template <typename fpt> + inline fpt pow7(fpt x) { return x * pow6(x); } +template <typename fpt> + inline fpt pow8(fpt x) { return pow2(pow2(pow2(x))); } + + // close namespace jtutil:: + }; + +//****************************************************************************** + +// +// This template does fuzzy comparisons and related operations on +// floating point values, parameterized by the floating point type. +// +// The fuzzy comparison semantics are based on those of APL, but are +// modified to use an absolute error tolerance for values close to 0. +// + +// this template class has only static members +// ... it's a class, not a namespace, because we want to express the +// semantics that the entire class is a single template, rather +// than the individual members being conceptually-unrelated templates +// ... moreover, we need the *data* member (template) tolerance , and +// it seems C++ doesn't grok data templates which aren't in a class +template <class fpt> +class fuzzy + { +public: + // comparison tolerance + // ... must be explicitly initialized when instantiating + // for a new <fpt> type, see "fuzzy.cc" for details/examples + // ... may be modified by user code if needed + static fpt tolerance; + + // fuzzy commparisons + static bool EQ(fpt x, fpt y); + static bool NE(fpt x, fpt y) { return ! EQ(x,y); } + static bool LT(fpt x, fpt y) { return EQ(x,y) ? false : (x < y); } + static bool LE(fpt x, fpt y) { return EQ(x,y) ? true : (x < y); } + static bool GT(fpt x, fpt y) { return EQ(x,y) ? false : (x > y); } + static bool GE(fpt x, fpt y) { return EQ(x,y) ? true : (x > y); } + + static bool is_integer(fpt x); // is x fuzzily an integer? + static int floor(fpt x); // round x fuzzily down to integer + static int ceiling(fpt x); // round x fuzzily up to integer + }; + +//****************************************************************************** + +// +// This template does machine-independent rounding of floating point +// values, parameterized by the floating point type. +// + +// this template class has only static members +// ... it's a class, not a namespace, because we want to express the +// semantics that the entire class is a single template, rather +// than the individual members being conceptually-unrelated templates +template <class fpt> +class round + { +public: + static int to_integer(fpt x); // round to nearest integer + + static int floor(fpt x); // round down to integer + static int ceiling(fpt x); // round up to integer + }; |