X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=third-party%2FOleanderStemmingLibrary%2Futilities%2Fsafe_math.h;fp=third-party%2FOleanderStemmingLibrary%2Futilities%2Fsafe_math.h;h=87acba191e7e1775c08bdc85b8ff39a87fc9cbe0;hb=5761a96f7859d86c7e2b27e521fa51a8e54c911d;hp=0000000000000000000000000000000000000000;hpb=01ce100d2fb24af549771ec159533e553479ac0e;p=wordring-tm%2Fwordring-tm.git diff --git a/third-party/OleanderStemmingLibrary/utilities/safe_math.h b/third-party/OleanderStemmingLibrary/utilities/safe_math.h new file mode 100644 index 0000000..87acba1 --- /dev/null +++ b/third-party/OleanderStemmingLibrary/utilities/safe_math.h @@ -0,0 +1,117 @@ +/** \addtogroup Mathematics + * Math and statistics classes. +* @{*/ +/** +\date 2015 +\copyright Oleander Software, Ltd. +\author Oleander Software, Ltd. +\details This program is free software; you can redistribute it and/or modify +it under the terms of the BSD License. +*/ + +#ifndef __SAFE_MATH_H__ +#define __SAFE_MATH_H__ + +#include +#include +#include + +//DIVISION OPERATIONS +//------------------- + +///Modulus operation that checks for modulus by zero or into zero (returns zero for those situations). +///@param dividend The dividend (i.e., the value being divided). +///@param divisor The divisor (i.e., the value dividing by). +///@returns The remainder of the modulus operation, or zero if one of the values was invalid. +template +inline T safe_modulus(const T dividend, const T divisor) + { + if (dividend == 0 || divisor == 0) + { return 0; } + return dividend%divisor; + } + +///Division operation that checks for division by zero or into zero (returns zero for those situations). +///@param dividend The dividend (i.e., the value being divided). +///@param divisor The divisor (i.e., the value dividing by). +///@returns The quotient of the division operation, or zero if one of the values was invalid. +///@note If the template type has a floating point precision, then the result will retain its precision. +template +inline T safe_divide(const T dividend, const T divisor) + { + if (dividend == 0 || divisor == 0) + { return 0; } + return dividend/static_cast(divisor); + } + +//DOUBLE OPERATIONS +//----------------- + +/**Compares two double values (given the specified precision). + @param actual The value being reviewed. + @param expected The expected value to compare against. + @param delta The tolerance of how different the values can be. The larger the delta, the + higher precision used in the comparison. + @returns True if the value matches the expected value.*/ +inline bool compare_doubles(const double actual, const double expected, const double delta = 1e-6) + { + assert(delta >= 0 && "delta value should be positive when comparing doubles"); + return (std::fabs(actual-expected) <= std::fabs(delta)); + } + +/**Compares two double values for less than (given the specified precision). + @param left The value being reviewed. + @param right The other value to compare against. + @param delta The tolerance of how different the values can be. The larger the delta, the + higher precision used in the comparison. + @returns True if the value is less than the other value.*/ +inline bool compare_doubles_less(const double left, const double right, const double delta = 1e-6) + { + assert(delta >= 0 && "delta value should be positive when comparing doubles"); + return std::fabs(left-right) > std::fabs(delta) && (left < right); + } + +/**Compares two double values for less than or equal to (given the specified precision). + @param left The value being reviewed. + @param right The other value to compare against. + @param delta The tolerance of how different the values can be. The larger the delta, the + higher precision used in the comparison. + @returns True if the value is less than or equal to the other value.*/ +inline bool compare_doubles_less_or_equal(const double left, const double right, const double delta = 1e-6) + { + assert(delta >= 0 && "delta value should be positive when comparing doubles"); + return compare_doubles_less(left,right,delta) || compare_doubles(left,right,delta); + } + +/**Compares two double values for greater than (given the specified precision). + @param left The value being reviewed. + @param right The other value to compare against. + @param delta The tolerance of how different the values can be. The larger the delta, the + higher precision used in the comparison. + @returns True if the value is greater than the other value.*/ +inline bool compare_doubles_greater(const double left, const double right, const double delta = 1e-6) + { + assert(delta >= 0 && "delta value should be positive when comparing doubles"); + return std::fabs(left-right) > std::fabs(delta) && (left > right); + } + +///"less" interface for double values. +class double_less : public std::binary_function + { +public: + inline bool operator()(const double& left, const double& right) const + { return compare_doubles_less(left,right); } + }; + +//INTEGER OPERATIONS +//------------------ + +///Converts an integral type to a boolean. Compilers complain about directly assigning +///an int to a bool (casting doesn't help either), so this works around that. +///@param intVal The integer value to convert to a boolean. +///@returns The boolean equivalent of the integer. +template +inline bool int_to_bool(const T intVal) + { return (intVal != 0); } + +#endif //__SAFE_MATH_H__