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 namespace Gecode { namespace Int {
00035
00036 inline bool
00037 Limits::valid(int n) {
00038 return ((n >= min) && (n <= max));
00039 }
00040 inline bool
00041 Limits::valid(long long int n) {
00042 return ((n >= min) && (n <= max));
00043 }
00044
00045 inline void
00046 Limits::check(int n, const char* l) {
00047 if ((n < min) || (n > max))
00048 throw OutOfLimits(l);
00049 }
00050 inline void
00051 Limits::check(long long int n, const char* l) {
00052 if ((n < min) || (n > max))
00053 throw OutOfLimits(l);
00054 }
00055
00056 inline void
00057 Limits::positive(int n, const char* l) {
00058 if ((n <= 0) || (n > max))
00059 throw OutOfLimits(l);
00060 }
00061 inline void
00062 Limits::positive(long long int n, const char* l) {
00063 if ((n <= 0.0) || (n > max))
00064 throw OutOfLimits(l);
00065 }
00066
00067 inline void
00068 Limits::nonnegative(int n, const char* l) {
00069 if ((n < 0) || (n > max))
00070 throw OutOfLimits(l);
00071 }
00072 inline void
00073 Limits::nonnegative(long long int n, const char* l) {
00074 if ((n < 0.0) || (n > max))
00075 throw OutOfLimits(l);
00076 }
00077
00078 forceinline bool
00079 Limits::overflow_add(int n, int m) {
00080 long long int nm =
00081 static_cast<long long int>(n) + static_cast<long long int>(m);
00082 return (nm > INT_MAX) || (nm < INT_MIN+1);
00083 }
00084 forceinline bool
00085 Limits::overflow_add(long long int n, long long int m) {
00086 if (m < 0)
00087 return n < LLONG_MIN + 1 - m;
00088 else
00089 return n > LLONG_MAX - m;
00090 }
00091
00092 forceinline bool
00093 Limits::overflow_sub(int n, int m) {
00094 long long int nm =
00095 static_cast<long long int>(n) - static_cast<long long int>(m);
00096 return (nm > INT_MAX) || (nm < INT_MIN+1);
00097 }
00098 forceinline bool
00099 Limits::overflow_sub(long long int n, long long int m) {
00100 if (m < 0)
00101 return n > LLONG_MAX + m;
00102 else
00103 return n < LLONG_MIN + 1 + m;
00104 }
00105
00106 inline bool
00107 Limits::overflow_mul(int n, int m) {
00108 long long int nm =
00109 static_cast<long long int>(n) * static_cast<long long int>(m);
00110 return (nm > INT_MAX) || (nm < INT_MIN+1);
00111 }
00112
00113 inline bool
00114 Limits::overflow_mul(long long int n, long long int m) {
00115
00116 if ((n == LLONG_MIN) || (m == LLONG_MIN))
00117 return false;
00118
00119 unsigned long long int un =
00120 static_cast<unsigned long long int>(n < 0 ? -n : n);
00121 unsigned long long int um =
00122 static_cast<unsigned long long int>(m < 0 ? -m : m);
00123
00124 const unsigned int k = CHAR_BIT * sizeof(int);
00125
00126 unsigned long long int un_hi = un >> k;
00127 unsigned long long int un_lo = un & ((1ULL << k) - 1ULL);
00128 unsigned long long int um_hi = um >> k;
00129 unsigned long long int um_lo = um & ((1ULL << k) - 1ULL);
00130
00131
00132 if ((un_hi != 0ULL) && (um_hi != 0ULL))
00133 return true;
00134
00135 unsigned long long int unm_hi = 0ULL;
00136
00137
00138 if (un_hi != 0ULL)
00139 unm_hi = un_hi * um_lo;
00140 else if (um_hi != 0ULL)
00141 unm_hi = um_hi * un_lo;
00142 else
00143 return false;
00144
00145
00146 if ((unm_hi >> k) != 0ULL)
00147 return true;
00148 unm_hi <<= k;
00149
00150 unsigned long long int unm_lo = un_lo * um_lo;
00151
00152 return unm_hi > static_cast<unsigned long long int>(LLONG_MAX) - unm_lo;
00153 }
00154
00155 }}
00156
00157