limits.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Int {
00039
00040 inline bool
00041 Limits::valid(int n) {
00042 return ((n >= min) && (n <= max));
00043 }
00044 inline bool
00045 Limits::valid(long long int n) {
00046 return ((n >= min) && (n <= max));
00047 }
00048
00049 inline void
00050 Limits::check(int n, const char* l) {
00051 if ((n < min) || (n > max))
00052 throw OutOfLimits(l);
00053 }
00054 inline void
00055 Limits::check(long long int n, const char* l) {
00056 if ((n < min) || (n > max))
00057 throw OutOfLimits(l);
00058 }
00059
00060 inline void
00061 Limits::positive(int n, const char* l) {
00062 if ((n <= 0) || (n > max))
00063 throw OutOfLimits(l);
00064 }
00065 inline void
00066 Limits::positive(long long int n, const char* l) {
00067 if ((n <= 0.0) || (n > max))
00068 throw OutOfLimits(l);
00069 }
00070
00071 inline void
00072 Limits::nonnegative(int n, const char* l) {
00073 if ((n < 0) || (n > max))
00074 throw OutOfLimits(l);
00075 }
00076 inline void
00077 Limits::nonnegative(long long int n, const char* l) {
00078 if ((n < 0.0) || (n > max))
00079 throw OutOfLimits(l);
00080 }
00081
00082 forceinline bool
00083 Limits::overflow_add(int n, int m) {
00084 long long int nm =
00085 static_cast<long long int>(n) + static_cast<long long int>(m);
00086 return (nm > INT_MAX) || (nm < INT_MIN+1);
00087 }
00088 forceinline bool
00089 Limits::overflow_add(long long int n, long long int m) {
00090 if (m < 0)
00091 return n < LLONG_MIN + 1 - m;
00092 else
00093 return n > LLONG_MAX - m;
00094 }
00095
00096 forceinline bool
00097 Limits::overflow_sub(int n, int m) {
00098 long long int nm =
00099 static_cast<long long int>(n) - static_cast<long long int>(m);
00100 return (nm > INT_MAX) || (nm < INT_MIN+1);
00101 }
00102 forceinline bool
00103 Limits::overflow_sub(long long int n, long long int m) {
00104 if (m < 0)
00105 return n > LLONG_MAX + m;
00106 else
00107 return n < LLONG_MIN + 1 + m;
00108 }
00109
00110 inline bool
00111 Limits::overflow_mul(int n, int m) {
00112 long long int nm =
00113 static_cast<long long int>(n) * static_cast<long long int>(m);
00114 return (nm > INT_MAX) || (nm < INT_MIN+1);
00115 }
00116
00117 inline bool
00118 Limits::overflow_mul(long long int n, long long int m) {
00119
00120 if ((n == LLONG_MIN) || (m == LLONG_MIN))
00121 return false;
00122
00123 unsigned long long int un =
00124 static_cast<unsigned long long int>(n < 0 ? -n : n);
00125 unsigned long long int um =
00126 static_cast<unsigned long long int>(m < 0 ? -m : m);
00127
00128 const unsigned int k = CHAR_BIT * sizeof(int);
00129
00130 unsigned long long int un_hi = un >> k;
00131 unsigned long long int un_lo = un & ((1ULL << k) - 1ULL);
00132 unsigned long long int um_hi = um >> k;
00133 unsigned long long int um_lo = um & ((1ULL << k) - 1ULL);
00134
00135
00136 if ((un_hi != 0ULL) && (um_hi != 0ULL))
00137 return true;
00138
00139 unsigned long long int unm_hi = 0ULL;
00140
00141
00142 if (un_hi != 0ULL)
00143 unm_hi = un_hi * um_lo;
00144 else if (um_hi != 0ULL)
00145 unm_hi = um_hi * un_lo;
00146 else
00147 return false;
00148
00149
00150 if ((unm_hi >> k) != 0ULL)
00151 return true;
00152 unm_hi <<= k;
00153
00154 unsigned long long int unm_lo = un_lo * um_lo;
00155
00156 return unm_hi > static_cast<unsigned long long int>(LLONG_MAX) - unm_lo;
00157 }
00158
00159 }}
00160
00161