33#ifndef SVF_NUMERICVALUE_H
34#define SVF_NUMERICVALUE_H
42#define epsilon std::numeric_limits<double>::epsilon();
152 return expr._iVal == 0;
173 return rhs.is_plus_infinity();
182 return rhs.is_plus_infinity();
201 return rhs.is_minus_infinity();
210 return rhs.is_minus_infinity();
285 if ((
lhs.is_plus_infinity() &&
rhs.is_minus_infinity()) ||
286 (
lhs.is_minus_infinity() &&
rhs.is_plus_infinity()))
288 assert(
false &&
"invalid add");
293 if (
lhs.is_plus_infinity() ||
rhs.is_plus_infinity())
300 if (
lhs.is_minus_infinity() ||
rhs.is_minus_infinity())
307 if (
lhs._iVal > 0 &&
rhs._iVal > 0 &&
308 (std::numeric_limits<s64_t>::max() -
lhs._iVal) <
rhs._iVal)
315 if (
lhs._iVal < 0 &&
rhs._iVal < 0 &&
316 (-std::numeric_limits<s64_t>::max() -
lhs._iVal) >
rhs._iVal)
323 return lhs._iVal +
rhs._iVal;
368 if (
lhs._iVal == 0 ||
rhs._iVal == 0)
373 if (
lhs.is_infinity() ||
rhs.is_infinity())
378 if (
lhs._iVal *
rhs._iVal > 0)
390 if (
lhs._iVal > 0 &&
rhs._iVal > 0 &&
391 (std::numeric_limits<s64_t>::max() /
lhs._iVal) <
rhs._iVal)
398 if (
lhs._iVal < 0 &&
rhs._iVal < 0 &&
399 (std::numeric_limits<s64_t>::max() /
lhs._iVal) >
rhs._iVal)
407 if ((
lhs._iVal > 0 &&
rhs._iVal < 0 &&
408 (-std::numeric_limits<s64_t>::max() /
lhs._iVal) >
rhs._iVal) ||
409 (
lhs._iVal < 0 &&
rhs._iVal > 0 &&
410 (-std::numeric_limits<s64_t>::max() /
rhs._iVal) >
lhs._iVal))
417 return lhs._iVal *
rhs._iVal;
424 assert(
false &&
"divide by zero");
425 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
426 return lhs._iVal %
rhs._iVal;
427 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
430 else if (
lhs.is_infinity() && !
rhs.is_infinity())
451 assert(
false &&
"divide by zero");
454 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
455 return lhs._iVal /
rhs._iVal;
456 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
458 else if (
lhs.is_infinity() && !
rhs.is_infinity())
515 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
518 else if (
lhs.is_infinity())
520 else if (
rhs.is_infinity())
521 return lhs.geq(0) ? 0 : -1;
523 return lhs._iVal >>
rhs._iVal;
533 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
536 else if (
lhs.is_infinity())
538 else if (
rhs.is_infinity())
541 return lhs._iVal <<
rhs._iVal;
567 return lhs._iVal ==
rhs._iVal &&
lhs._isInf ==
rhs._isInf;
575 if (
lhs.is_minus_infinity() ||
rhs.is_minus_infinity())
577 else if(
lhs.is_plus_infinity())
579 else if(
rhs.is_plus_infinity())
591 if (
lhs.is_plus_infinity() ||
rhs.is_plus_infinity())
593 else if(
lhs.is_minus_infinity())
595 else if(
rhs.is_minus_infinity())
608 for (
const auto& it :
_l)
610 if (it.is_minus_infinity())
612 else if (!it.geq(ret))
626 for (
const auto& it :
_l)
628 if (it.is_plus_infinity())
630 else if (!it.leq(ret))
671 return std::numeric_limits<s64_t>::min();
677 return std::numeric_limits<s64_t>::max();
697 return std::to_string(
_iVal);
714 assert(
false &&
"cannot get real number for integer!");
720 assert(
false &&
"cannot get real number for integer!");
757 if (std::isinf(
a) && std::isinf(
b))
769 return _fVal == std::numeric_limits<double>::infinity();
774 return _fVal == -std::numeric_limits<double>::infinity();
794 return std::numeric_limits<double>::infinity();
799 return -std::numeric_limits<double>::infinity();
827 return rhs.is_plus_infinity();
835 return rhs.is_plus_infinity();
851 return rhs.is_minus_infinity();
859 return rhs.is_minus_infinity();
914 if ((
lhs == std::numeric_limits<double>::infinity() &&
915 rhs == -std::numeric_limits<double>::infinity()) ||
916 (
lhs == -std::numeric_limits<double>::infinity() &&
917 rhs == std::numeric_limits<double>::infinity()))
919 assert(
false &&
"invalid add");
925 if (res == std::numeric_limits<double>::infinity())
933 if (res == -std::numeric_limits<double>::infinity())
942 (std::numeric_limits<double>::max() -
lhs) <
rhs)
944 res = std::numeric_limits<double>::infinity();
953 (-std::numeric_limits<double>::max() -
lhs) >
rhs)
955 res = -std::numeric_limits<
998 if (res == std::numeric_limits<double>::infinity())
1006 if (res == -std::numeric_limits<double>::infinity())
1012 if (
lhs > 0 &&
rhs > 0 &&
1013 lhs > std::numeric_limits<double>::max() /
rhs)
1015 return std::numeric_limits<double>::infinity();
1017 if (
lhs < 0 &&
rhs < 0 &&
1018 lhs < std::numeric_limits<double>::max() /
rhs)
1020 return std::numeric_limits<double>::infinity();
1024 if (
lhs > 0 &&
rhs < 0 &&
1025 rhs < std::numeric_limits<double>::lowest() /
lhs)
1027 return -std::numeric_limits<double>::infinity();
1030 lhs < std::numeric_limits<double>::lowest() /
rhs)
1032 return -std::numeric_limits<double>::infinity();
1058 return (
lhs >= 0.0f) ? std::numeric_limits<double>::infinity()
1059 : -std::numeric_limits<double>::infinity();
1063 if (res == std::numeric_limits<double>::infinity())
1071 if (res == -std::numeric_limits<double>::infinity())
1078 if (
rhs > 0 &&
rhs < std::numeric_limits<double>::min() &&
1079 lhs > std::numeric_limits<double>::max() *
rhs)
1081 return std::numeric_limits<double>::infinity();
1084 lhs > std::numeric_limits<double>::max() *
rhs)
1086 return -std::numeric_limits<double>::infinity();
1102 assert(
false &&
"divide by zero");
1103 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
1104 return std::fmod(
lhs._fVal,
rhs._fVal);
1105 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
1108 else if (
lhs.is_infinity() && !
rhs.is_infinity())
1166 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1169 else if (
lhs.is_infinity())
1171 else if (
rhs.is_infinity())
1172 return lhs.geq(0) ? 0 : -1;
1180 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1183 else if (
lhs.is_infinity())
1185 else if (
rhs.is_infinity())
1194 return cond.
_fVal != 0.0f ?
lhs._fVal :
rhs._fVal;
1211 return std::min(
lhs._fVal,
rhs._fVal);
1216 return std::max(
lhs._fVal,
rhs._fVal);
1222 for (
const auto& it :
_l)
1224 if (it.is_minus_infinity())
1226 else if (!it.geq(ret))
1237 for (
const auto& it :
_l)
1239 if (it.is_plus_infinity())
1241 else if (!it.leq(ret))
1256 return _fVal != 0.0f;
1272 return std::round(
_fVal);
1288 return std::to_string(
_fVal);
BoundedDouble & operator=(const BoundedDouble &rhs)
friend BoundedDouble max(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool operator!=(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool operator<=(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator%(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool operator<(const BoundedDouble &lhs, const BoundedDouble &rhs)
const double getFVal() const
friend BoundedDouble operator>>(const BoundedDouble &lhs, const BoundedDouble &rhs)
static double safeDiv(double lhs, double rhs)
friend BoundedDouble operator*(const BoundedDouble &lhs, const BoundedDouble &rhs)
static double safeMul(double lhs, double rhs)
static BoundedDouble minus_infinity()
friend BoundedDouble operator!(const BoundedDouble &lhs)
friend BoundedDouble ite(const BoundedDouble &cond, const BoundedDouble &lhs, const BoundedDouble &rhs)
static BoundedDouble plus_infinity()
friend BoundedDouble operator&&(const BoundedDouble &lhs, const BoundedDouble &rhs)
bool equal(const BoundedDouble &rhs) const
BoundedDouble & operator=(BoundedDouble &&rhs)
void set_minus_infinity()
s64_t getIntNumeral() const
static bool isZero(const BoundedDouble &expr)
static bool doubleEqual(double a, double b)
bool geq(const BoundedDouble &rhs) const
friend BoundedDouble operator-(const BoundedDouble &lhs)
friend BoundedDouble operator-(const BoundedDouble &lhs, const BoundedDouble &rhs)
s64_t getNumeral() const
Return Numeral.
friend BoundedDouble operator|(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble min(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator^(const BoundedDouble &lhs, const BoundedDouble &rhs)
static double safeAdd(double lhs, double rhs)
friend BoundedDouble abs(const BoundedDouble &lhs)
friend BoundedDouble operator<<(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator/(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool eq(const BoundedDouble &lhs, const BoundedDouble &rhs)
static BoundedDouble min(std::vector< BoundedDouble > &_l)
friend BoundedDouble operator+(const BoundedDouble &lhs, const BoundedDouble &rhs)
BoundedDouble(const BoundedDouble &rhs)
bool is_minus_infinity() const
BoundedDouble(BoundedDouble &&rhs)
bool leq(const BoundedDouble &rhs) const
bool is_plus_infinity() const
virtual const std::string to_string() const
static BoundedDouble max(std::vector< BoundedDouble > &_l)
friend BoundedDouble operator&(const BoundedDouble &lhs, const BoundedDouble &rhs)
double getRealNumeral() const
friend bool operator>=(const BoundedDouble &lhs, const BoundedDouble &rhs)
BoundedDouble(double fVal)
friend BoundedDouble operator||(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool operator==(const BoundedDouble &lhs, const BoundedDouble &rhs)
Reload operator.
friend std::ostream & operator<<(std::ostream &out, const BoundedDouble &expr)
friend bool operator>(const BoundedDouble &lhs, const BoundedDouble &rhs)
A class representing a bounded 64-bit integer.
static BoundedInt plus_infinity()
friend BoundedInt operator||(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt ite(const BoundedInt &cond, const BoundedInt &lhs, const BoundedInt &rhs)
friend bool operator<=(const BoundedInt &lhs, const BoundedInt &rhs)
bool is_minus_infinity() const
friend bool operator<(const BoundedInt &lhs, const BoundedInt &rhs)
s64_t getNumeral() const
Retrieves the numeral value of the BoundedInt object.
bool is_plus_infinity() const
friend BoundedInt operator%(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator<<(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt min(std::vector< BoundedInt > &_l)
friend BoundedInt operator&(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt safeMul(const BoundedInt &lhs, const BoundedInt &rhs)
Performs safe multiplication of two BoundedInt objects.
const double getFVal() const
friend BoundedInt operator*(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt abs(const BoundedInt &lhs)
BoundedInt(BoundedInt &&rhs)
friend BoundedInt operator|(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator/(const BoundedInt &lhs, const BoundedInt &rhs)
friend bool operator!=(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt max(const BoundedInt &lhs, const BoundedInt &rhs)
s64_t getIntNumeral() const
friend bool operator>(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator+(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator>>(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator!(const BoundedInt &lhs)
friend BoundedInt operator^(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator&&(const BoundedInt &lhs, const BoundedInt &rhs)
BoundedInt & operator=(const BoundedInt &rhs)
friend std::ostream & operator<<(std::ostream &out, const BoundedInt &expr)
static BoundedInt max(std::vector< BoundedInt > &_l)
friend bool eq(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt safeAdd(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt minus_infinity()
friend BoundedInt min(const BoundedInt &lhs, const BoundedInt &rhs)
bool geq(const BoundedInt &rhs) const
bool equal(const BoundedInt &rhs) const
BoundedInt & operator=(BoundedInt &&rhs)
bool leq(const BoundedInt &rhs) const
static bool isZero(const BoundedInt &expr)
double getRealNumeral() const
BoundedInt(s64_t fVal, bool isInf)
void set_minus_infinity()
friend BoundedInt operator-(const BoundedInt &lhs)
friend BoundedInt operator-(const BoundedInt &lhs, const BoundedInt &rhs)
friend bool operator>=(const BoundedInt &lhs, const BoundedInt &rhs)
BoundedInt(const BoundedInt &rhs)
virtual const std::string to_string() const
friend bool operator==(const BoundedInt &lhs, const BoundedInt &rhs)
Reload operator.
llvm::IRBuilder IRBuilder