#include #include #include template struct Precision { public: static Type GetEps() { return eps; } static void SetEps(Type e) { eps = e; } private: static Type eps; }; template Type Precision::eps = static_cast(1E-7); template bool IsDoubleEqual(DigType d1, DigType d2) { return (fabs(d1 - d2) < Precision::GetEps()); } template DigType IntegerPart(DigType value) { return (value > 0) ? floor(value) : ceil(value); } template DigType FractionPart(DigType value) { return fabs(IntegerPart(value) - value); } template bool IsInteger(const Type& value) { return false; } #define GEN_CHECK_INTEGER(type) \ template<> \ bool IsInteger(const type& value) \ { \ return true; \ } #define GEN_CHECK_CMPL_INTEGER(type) \ template<> \ bool IsInteger >(const std::complex& value) \ { \ type zero = type(); \ return value.imag() == zero; \ } #define GEN_CHECK_REAL(type) \ template<> \ bool IsInteger(const type& value) \ { \ type zero = type(); \ return IsDoubleEqual(FractionPart(value), zero); \ } #define GEN_CHECK_CMPL_REAL(type) \ template<> \ bool IsInteger >(const std::complex& value) \ { \ type zero = type(); \ return IsDoubleEqual(value.imag(), zero); \ } #define GEN_INTEGER(type) \ GEN_CHECK_INTEGER(type) \ GEN_CHECK_CMPL_INTEGER(type) #define GEN_REAL(type) \ GEN_CHECK_REAL(type) \ GEN_CHECK_CMPL_REAL(type) GEN_INTEGER(char) GEN_INTEGER(unsigned char) GEN_INTEGER(short) GEN_INTEGER(unsigned short) GEN_INTEGER(int) GEN_INTEGER(unsigned int) GEN_INTEGER(long) GEN_INTEGER(unsigned long) GEN_INTEGER(long long) GEN_INTEGER(unsigned long long) GEN_REAL(float) GEN_REAL(double) GEN_REAL(long double) template inline void TestValue(const Type& value) { std::cout << "Value: " << value << " of type: " << typeid(Type).name() << " is integer - " << std::boolalpha << IsInteger(value) << std::endl; } int main() { char c = -100; unsigned char uc = 200; short s = c; unsigned short us = uc; int i = s; unsigned int ui = us; long long ll = i; unsigned long long ull = ui; std::complex ci1(2, 0); std::complex ci2(2, 4); std::complex ci3(-2, 4); std::complex cs1(2, 0); std::complex cs2(2, 4); std::complex cs3(-2, 4); std::complex cd1(2, 0); std::complex cf1(2, 4); std::complex cd2(-2, 4); float f1 = 1.0; float f2 = -2.0; float f3 = -2.4f; float f4 = 1.23e-5f; float f5 = 1.23e-10f; double d1 = f5; TestValue(c); TestValue(uc); TestValue(s); TestValue(us); TestValue(i); TestValue(ui); TestValue(ll); TestValue(ull); TestValue(ci1); TestValue(ci2); TestValue(ci3); TestValue(cs1); TestValue(cs2); TestValue(cs3); TestValue(cd1); TestValue(cd2); TestValue(cf1); TestValue(f1); TestValue(f2); TestValue(f3); TestValue(f4); TestValue(f5); std::cout << "Set float precision: 1e-15f\n"; Precision::SetEps(1e-15f); TestValue(f5); TestValue(d1); return 0; }